Subversion Repositories vnag

Compare Revisions

No changes between revisions

Regard whitespace Rev 1 → Rev 2

/trunk/LICENSE
0,0 → 1,202
 
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
 
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 
1. Definitions.
 
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
 
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
 
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
 
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
 
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
 
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
 
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
 
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
 
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
 
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
 
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
 
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
 
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
 
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
 
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
 
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
 
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
 
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
 
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
 
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
 
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
 
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
 
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
 
END OF TERMS AND CONDITIONS
 
APPENDIX: How to apply the Apache License to your work.
 
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
 
Copyright 2018 Daniel Marschall, ViaThinkSoft
 
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
 
http://www.apache.org/licenses/LICENSE-2.0
 
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
/trunk/TODO
0,0 → 1,34
 
TODO
----
 
- make proper documentation
- allow changing automatic help page to describe which individual ranges stand for (is it already possible, by getting the argument object and then changing its help text?)
- everywhere getter and setter instead of accessing class member variables
- ipfm monitor: dygraph has MIT license
- *.conf files: /daten sollte nicht in den example conf's stehen. irgendwie anders machen (Aber achtung: wir symlinken die config files in unserem /etc )
- idea: a script that converts the output of an EXISTING nagios plugin into VNag Weboutput. So an arbitary Nagios script can be forwarded to other systems over HTTP
- make all plugins "web enabled"
In the framework create an easy function, which generates a simple default HTML header and footer
- should error details, e.g. defective hard disks at the mdstat monitor be Verbosity=Summary, or Verbosity=AdditionalInformation ?
- idea for a new plugin: sudo /daten/scripts/tools/check_etc_perms | grep -v "world readable" | grep -v "world executable"
- should putputID, passwordOut and privateKey be a default argument? Then you can use encryption/signing for all plugins by default
- In re syntax checking/getopt:
* Evaluate if PHP 7.1 (with getopt()'s $optind) is able to detect unexpected CLI parameters for us (so we can output a syntax warning)
* Limit warning range numbers (avoid user adds too many, e.g. "-w A,B,C" although only 2 are allowed)
 
Future
------
 
- For arguments (warning/critical), also accept mixed UOMs, e.g. MB and %
- In re usage page:
* Automatic creation of usage page. Which arguments are necessary?
* Automatically generate syntax?
- Allow individual design via CSS
- Check if regex of validateLongOpt() is accurate
 
Unsure
------
 
- Automatically encrypt/sign via a global config setting?
- Should we also allow other UOMs?
/trunk/build_stable
0,0 → 1,30
#!/bin/bash
 
# Get the directory of this script (also works with symlinks)
# http://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
 
cd "$DIR"
./signtool/sign framework/* plugins/*/*
 
dirname=$( basename "$( pwd )" )
tmpfile=$( mktemp )
 
FILENAME="stable.tar.gz"
 
cd ..
tar cvfz "$tmpfile" \
--exclude="$dirname"/"$FILENAME" \
--exclude="$dirname"/signtool/private.pem \
--exclude "$dirname"/plugins_intern \
--exclude="$dirname"/_mock \
-- "$dirname"
 
# otherwise: "the file has changed while reading"
mv "$tmpfile" "$dirname"/"$FILENAME"
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/doc/vnag_model_1.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/doc/vnag_model_2.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/doc/vnag_model_3.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/doc/vnag_models_draw_io_source.xml
0,0 → 1,0
<mxfile userAgent="Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36" version="8.9.5" editor="www.draw.io" type="device"><diagram id="b67284ce-b3fd-41bd-dfda-fc1243b1e751" name="Page-1">7Vxbc5s4FP41fqwHkMDwGKdptzPZNrOZ3baPMig2Dba8ICfO/vqVDMLoQoxtsJ0UPyRwACGd+3ckMQDX8/XnFC1nf5IIJwPHitYD8HHgODZ0PPaPU15yygg6OWGaxlFx05ZwH/+HC6JVUFdxhDPpRkpIQuOlTAzJYoFDKtFQmpJn+bYHkshvXaIp1gj3IUp06vc4orOc6othcfofOJ7OxJttL8ivTFD4OE3JalG8b+CAh80vvzxHoq1ioNkMReS5QgI3A3CdEkLzo/n6Giect4Jt+XOfaq6W/U7xgjZ5AOQPPKFkVQz9K0nniN8yJ4uYkjReTHk/wzRe0qLP9EXwaTNSzNuyBmD8PIspvl+ikF99ZprBaDM6T9iZzQ4zmpLHkp+c8kAWtBC+w89REk8X7CRkvccpI+jDKUb4hFOK1xVSMbzPmMwxTV/YLcVVYBWsLlTRdmB+/rwVrD0q7plVhCpoqNCladn0lp/soGCpmb1QY+/A8RJaDF3ipffviogLH7INU67YDba3XG8YIa6zoyn//89XxAXzKUVz/EzSR9HwJD2qWdEMG1neRUHuTPK2Z5I8F3DMDPKquDCPo4i/uxOVCBqqhNOCSnjHqwRkstME923yi3tC7ii5H8LcO85w+MhkVNGM/YTMvNOSH4arCd4t5UmuEreTklA6w28rmsQLfFZHYGuOwNKl7pgcweh4qfsGqSvMxovoiocuPuwEZVkcbliFUqqTK1xXWccYlL78KOxyc/KTnwxdfrqO6Y/iOX68vVLL34ys0hBLqsu6NMVUih84kuKpLoMKj10DiwUtxQmi8ZMchU18L95wR+KNzdSI2PGh3EQ+muKpalhUG3KVhoDSUM4DraGNGpTDbqQZQa0/iOIn1WCr1sr8f0yyWlPWH2C3XN9+2fEAI0vvrfEIM7xGU8JMdLzEacyGy61UUO8EybnUpMAFDXwBMCiq30IEsAPd9pn93BenJKUzwriIkpstdSwYz9zoIzuVw2+Fn8LELcnEgfIrLt5VZGdVfYet+45fmNKXQi5oxYIMGG97ekvIskZ8jTyLDXXXEjR0LY19RmP56Fnb3xnjUZ0trObJVcgy5UrWcosmOLkjWUxjbiQfJ4RSMmc3JPzCuIyL1yThz33cwgQ986FEMRmSB9PrEvtYZ7OjkWpHULcjkxl5bZjR6MCY+lrwNFqPu8M0Gql48OaCZ9BW8ISdBU/htis68B1PPtws0CThie97BbHAOiGILbvbo9h9UWwXoh+dEKwKl9qj1XOj1VINToFWDWXBZqH1ouCq6HQ15AqOXWjMhV5LMRfa3cXc+qLmBjnudglMcgaXsK9jMbeyByo+vKM9jhY42nF3eyng6vbTBo4W7+5x9NblGUp0wl5PD6QNte4eSDcD0sBQkOoKSDtvC0g7hlrRpYf1UVth3ekurOuF6DGfSH/FXt948AJK8CqLwrtS7DaCFwB98FIMG5jy9bNVgUVv+uC1Owu0FUNyTxe8gI5G3mUF0Al8iceeH+jOqqsKoMjgjykDuSYo9Vr571yVvJOJcOQ2FGEblTzQrzs5k9g1w3WbZRltFPLAoan9RRXygGnhSVNUe5qMXxGyDwO5hcYJP1R8RKA01F7CD0xrkvo63m9axwO7nVRXdTzQr4dRPZ5YRiF5PL+hx2sdCone9FBopyGNHMV/W7ohdQWFoGme/nLreEKf31BUd1uK6r7VWVQXG21+ozKeJzM3sH09dnVVxhNLm/rYtY1drm7XQivPELv00kUfu2qSQFcxJKAbUmexSy9P8DLeXxhFXFjvpYqn7TyyIBwaUu3O9qOZ6gH9Uj5Z+idbymfbdmPpt1EDFEWJHvH3iF9ducM8UWDSxa5Av8jQ+8SpTJxcsdO9mjidbf7T1dFknzg13AVjeSZb6ip3cnXIp9tWB7h/aNmObCIeBIKgWlUjCxDaLlmA19ACTlMScIHsN31QhvB9qwLQt5SmgNpUe3UB17Rq91glKad8hiO3qgmSBpUzQD/3UgVHVwXB+gtRBajU+nyBl/ZVBBDIOhU4SkMtqoFpJr89NWhbC0y75sR9F6IFwJeFB9Wt4odqwahDLTAtBmhPC5xX1MA5zBuYZoAvzBtAxZvDA70BBGqxuDs90MsBX3hatMB6dYU9GS+zahYeJmQVXSq+AZbCRbHrvgpuPEdXh1bAjT61/n74ChV3Z1g02xVfRbZc4WtRdRKfILtZo/kywdmA10s+sb8Ms7C/Ico4TWE9GzI18VTgkQXhS4fGD3GSKKTmnysyCVHGrVWpbSfPNIkY5KYLSQhFl4lvmgEBbchkP/RRMLAmkPDxRyibbZhzfFRRQsMRYeZs2QWUF2YEqsgaZxcioS7Dk9JQe1HF22/36OEaoYOOA8VeizXOJnbXGcp+1rZcOPQOlL3WGssphk5n8t8Pah4u/73Rxr6KUQ8/zphlDkEQ+CPoQ+C6UEzolCvvDwQfvF1bCexw6FiVX2elCU/HpP/E2WrzEUqyosuVnjQdH7kT/EBbi9v+kWG7hJKBJAIQ6Dmra6jH222EcR0S/p5CgEC2g5HvnU4I9dOzdRN0XAgfCn7yia9006PaKbpsiRaCdjOf4CjKN8mgcMbXyXP/hCK+dYYdRoiiyqRY9dGGc2UXl2C3pCNMKRQd0av9osZyZL7NTrdfA86d6/aTy+Dmfw==</diagram></mxfile>
/trunk/framework/vnag_framework.inc.php
0,0 → 1,2464
<?php /* <ViaThinkSoftSignature>i1Ox4pM0A5UeIZrXsnfEQNOTzk0ajnmpk57FeGqfm6NfPzJn2WB6PgTV1mt61S0DeXbj4756UEGFYmRASqM9SC4r4GR4PLgZ7+gZ99D2kezXEqu1BpXozrw65BRRgls9u18g4i1oU+V5+/zqCFlDRSXS3UCoeReHtYdZG6Ve9JhI0xB2eG4LL+n1mAsC810LhCngHIqP6W5LDgufSiWT8cmJIATcVnVF8AgAVCe6qDrkzFL1/KlHUsjdWYdExkERM2miWt25wdDk5NGUvqs/L6PUVS/0AHZLoNnFmZtUpobIfMXboSF4GxSbC/j2UVrvTnS1gNLSPEe26U7gbCTXD+3ixpEWUiTVFsLN9KlS1KpvZO/FHafYqiV7WvdjD1wLeXvPQ7/mcZAzRW837FR6ouoZwJnOv5iFAIQFn9Ci0UGtvu6HJV1jnctkkkrfdaK+tf+w2FegLvisDHWMm2NFX5soFokVkPKPqu+b4HjJhsjv8FWo9a4INiQBSQ60IaU5mIeLC4GlYSf6otP6r74O2TUUZzWEd/vhe0ZoQK/HuAnnibT7ftBHrTfSmdQ258/1mvMB7+sG1OT8YpCSM8RqdN3PtKt/qFK6DBXiCkrL45NuarVhu0v0gbN+Wsq4SHiEkK2iDsFZPbHLNGqh1qrV23AUKYdxNpsypVboe74DcV3Rg51maiYavMbs4Zk9sy+0b0VjHI3MorKK/FV3nr6HeCJEGyV2pWu45wGGfFQ9vZntZxeZ/V6LNd0Dcbp4HgLix4mTA3bz1YMDtrCRKUt7oY7rKAdTCC+iJzGUUBTquf5HsCEbG+ztY1oHk4uN9IJ1r2eu/38XfUJm+4wUyX8mXNOzSPA2SqKrz3gvJRkDZ+E1ZN6KbaEIV17ae7exSWoYyZm3ML0fFrwQG+9GiWBmyEqQ8Ad5YxtWOnvCTHvFbEYl0TqpcnPDEhcEoU7Cv/78G+wezq3aUo4ij3n7yjyDOW6BphHpA6yMFyx2AAj4u8c/LNpssVBFUwAkh1SAochIN0hzo3Kfx/csJSzeOSTVUbS1NdAR0Xb/POii7tM/Pka9yUZ6b0Y+5goKBKIpEPxJfb0rLelmLB2DtL0sKqHg9BDpGjyHeSffXLCHs9bDP93F/7SFONrDSXoAaVfJuh8duW31lfBoiIEN0X8X4a0ZqRPCbMcPgOq5VF3NoDe26SFhnR1VE78u1xdJorNc1yW16fcYDW1mDBLmsZRbTShlACvUoW58SdHPFM5aoZFwhNtqmqzjqte5qdDvz2EWkS8KB+8Z+Ve2UvfQ5yVkyjLp3HLo1XJeDphQGdHooYyZBQUtvTDJ1F2ZwfC+a6iimM5SGB9eJfXEHH5uPtJW0TsgsQ==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
 
VNag - Nagios Framework for PHP (C) 2014-2018
__ ___ _____ _ _ _ ____ __ _
\ \ / (_) __ |_ _| |__ (_)_ __ | | __/ ___| ___ / _| |_
\ \ / /| |/ _` || | | '_ \| | '_ \| |/ /\___ \ / _ \| |_| __|
\ V / | | (_| || | | | | | | | | | < ___) | (_) | _| |_
\_/ |_|\__,_||_| |_| |_|_|_| |_|_|\_\|____/ \___/|_| \__|
 
Developed by Daniel Marschall www.viathinksoft.com
Licensed under the terms of the Apache 2.0 license
Revision 2018-11-04
 
*/
 
/****************************************************************************************************
 
Introduction:
 
VNag is a small framework for Nagios Plugin Developers who use PHP CLI scripts.
The main purpose of VNag is to make the development of plugins as easy as possible, so that
the developer can concentrate on the actual work. VNag will try to automate as much
as possible.
 
Please note that your script should include the +x chmod flag:
chmod +x myscript.php
 
Please see the the demo/ folder for a few examples how to use this framework.
 
Arguments:
 
Example:
$this->addExpectedArgument($argSilent = new VNagArgument('s', 'silent', VNagArgument::VALUE_FORBIDDEN, null, 'Description for the --silent output', $defaultValue));
$this->addExpectedArgument($argHost = new VNagArgument('H', 'host', VNagArgument::VALUE_REQUIRED, 'hostname', 'Description for the --host output', $defaultValue));
 
In the example above, the two argument objects $argSilent and $argHost were created.
With these objects of the type VNagArgument, you can query the argument's value,
how often the argument was passed and if it is set:
 
$argSilent->count(); // 1 if "-s" is passed, 2 if "-s -s" is passed etc.
$argSilent->available(); // true if "-s" is passed, false otherwise
$argHost->getValue(); // "example.com" if "-h example.com" is passed
 
It is recommended that you pass every argument to $this->addExpectedArgument() .
Using this way, VNag can generate a --help page for you, which lists all your arguments.
Future version of VNag may also require to have a complete list of all valid arguments,
since the Nagios Development Guidelines recommend to output the usage information if an illegal
argument is passed. Due to PHP's horrible bad implementation of GNU's getopt(), this check for
unknown arguments is currently not possible, and the developer of VNag does not want to use
dirty hacks/workarounds, which would not match to all argument notation variations/styles.
See: https://bugs.php.net/bug.php?id=68806
https://bugs.php.net/bug.php?id=65673
https://bugs.php.net/bug.php?id=26818
 
Setting the status:
 
You can set the status with:
$this->setStatus(VNag::STATUS_OK);
If you don't set a status, the script will return Unknown instead.
setStatus($status) will keep the most severe status, e.g.
$this->setStatus(VNag::STATUS_CRITICAL);
$this->setStatus(VNag::STATUS_OK);
will result in a status "Critical".
If you want to completely overwrite the status, use $force=true:
$this->setStatus(VNag::STATUS_CRITICAL);
$this->setStatus(VNag::STATUS_OK, true);
The status will now be "OK".
 
Possible status codes are:
(For service plugins:)
VNag::STATUS_OK = 0;
VNag::STATUS_WARNING = 1;
VNag::STATUS_CRITICAL = 2;
VNag::STATUS_UNKNOWN = 3;
 
(For host plugins:)
VNag::STATUS_UP = 0;
VNag::STATUS_DOWN = 1;
 
Output:
 
After the callback function cbRun() of your job has finished,
the framework will automatically output the results in the Nagios console output format,
the visual HTML output and/or the invisible HTML output.
 
In case of CLI invokation, the Shell exit code will be remembered and
automatically returned by the shutdown handler once the script normally
terminates. (In case you run different jobs, which is not recommended, the
shutdown handler will output the baddest exit code).
 
The Shell output format will be:
<Service status text>: <Comma separates messages> | <whitespace separated primary performance data>
"Verbose information:"
<Multiline verbose output> | <Multiline secondary performance data>
 
<Service status text> will be automatically created by VNag.
 
Verbose information are printed below the first line. Most Nagios clients will only print the first line.
If you have important output, use $this->setHeadline() instead.
You can add verbose information with following method:
$this->addVerboseMessage('foobar', $verbosity);
 
Following verbosity levels are defined:
VNag::VERBOSITY_SUMMARY = 0; // always printed
VNag::VERBOSITY_ADDITIONAL_INFORMATION = 1; // requires at least -v
VNag::VERBOSITY_CONFIGURATION_DEBUG = 2; // requiers at least -vv
VNag::VERBOSITY_PLUGIN_DEBUG = 3; // requiers at least -vvv
 
All STDOUT outputs of your script (e.g. by echo) will be interpreted as "verbose" output
and is automatically collected, so
echo "foobar";
has the same functionality as
$this->addVerboseMessage('foobar', VNag::VERBOSITY_SUMMARY);
 
You can set messages (which will be added into the first line, which is preferred for plugin outputs)
using
$this->setHeadline($msg, $append, $verbosity);
Using the flag $append, you can choose if you want to append or replace the message.
 
VNag will catch Exceptions of your script and will automatically end the plugin,
returning a valid Nagios output.
 
Automatic handling of basic arguments:
 
VNag will automatic handle of following CLI arguments:
-?
-V --version
-h --help
-v --verbose
-t --timeout (only works if you set declare(ticks=1) at the beginning of each of your scripts)
-w --warning
-c --critical
 
You can performe range checking by using:
$example_value = '10MB';
$this->checkAgainstWarningRange($example_value);
this is more or less the same as:
$example_value = '10MB';
$wr = $this->getWarningRange();
if (isset($wr) && $wr->checkAlert($example_value)) {
$this->setStatus(VNag::STATUS_WARNING);
}
 
In case that your script allows ranges which can be relative and absolute, you can provide multiple arguments;
$wr->checkAlert() will be true, as soon as one of the arguments is in the warning range.
The check will be done in this way:
$example_values = array('10MB', '5%');
$this->checkAgainstWarningRange($example_values);
this is more or less the same as:
$example_values = array('10MB', '5%');
$wr = $this->getWarningRange();
if (isset($wr) && $wr->checkAlert($example_values)) {
$this->setStatus(VNag::STATUS_WARNING);
}
 
Note that VNag will automatically detect the UOM (Unit of Measurement) and is also able to convert them,
e.g. if you use the range "-w 20MB:40MB", your script will be able to use $wr->checkAlert('3000KB')
 
Please note that only following UOMs are accepted (as defined in the Plugin Development Guidelines):
- no unit specified: assume a number (int or float) of things (eg, users, processes, load averages)
- s, ms, us: seconds
- %: percentage
- B, KB, MB, TB: bytes // NOTE: GB is not in the official development guidelines,probably due to an error, so I've added them anyway
- c: a continous counter (such as bytes transmitted on an interface)
 
Multiple warning/critical ranges:
 
The arguments -w and -c can have many different values, separated by comma.
We can see this feature e.g. with the official plugin /usr/lib/nagios/plugins/check_ping:
It has following syntax for the arguments -w and -c: <latency>,<packetloss>%
 
When you are using checkAgainstWarningRange, you can set the fourth argument to the range number
you would like to check (beginning with 0).
 
Example:
// -w 1MB:5MB,5%:10%
$this->checkAgainstWarningRange('4MB', true, true, 0); // check value 4MB against range "1MB:5MB" (no warning)
$this->checkAgainstWarningRange('15%', true, true, 1); // check value 15% gainst range "5%:10%" (gives warning)
 
Visual HTTP output:
 
Can be enabled/disabled with $this->http_visual_output
 
Valid values:
 
VNag::OUTPUT_SPECIAL = 1; // illegal usage / help page, version page
VNag::OUTPUT_NORMAL = 2;
VNag::OUTPUT_EXCEPTION = 4;
VNag::OUTPUT_ALWAYS = 7;
VNag::OUTPUT_NEVER = 0;
 
Encryption and Decryption:
 
In case you are emitting machine readable code in your HTTP output
(can be enabled/disabled by $this->http_invisible_output),
you can encrypt the machine readable part of your HTTP output by
setting $this->password_out . If you want to read the information,
you need to set $this->password_in at the web-reader plugin.
 
You can sign the output by setting $this->privkey with a filename containing
a private key created by OpenSSL. If it is encrypted, please also set
$this->privkey_password .
To check the signature, set $this->pubkey at your web-reader plugin with
the filename of the public key file.
 
Attention!
- An empty string is also considered as password. If you don't want to encrypt the
machine readable output, please set $this->password_out to null.
- Both features (encryption and signatures) require the OpenSSL plugin in PHP.
 
Performance data:
 
You can add performance data using
$this->addPerformanceData(new VNagPerformanceData($label, $value, $warn, $crit, $min, $max));
or by the alternative constructor
$this->addPerformanceData(VNagPerformanceData::createByString("'XYZ'=100;120;130;0;500"));
$value may contain an UOM, e.g. "10MB". All other parameters may not contain an UOM.
 
Guidelines:
 
This framework currently supports meets following guidelines:
- https://nagios-plugins.org/doc/guidelines.html#PLUGOUTPUT (Plugin Output for Nagios)
- https://nagios-plugins.org/doc/guidelines.html#AEN33 (Print only one line of text)
- https://nagios-plugins.org/doc/guidelines.html#AEN41 (Verbose output)
- https://nagios-plugins.org/doc/guidelines.html#AEN78 (Plugin Return Codes)
- https://nagios-plugins.org/doc/guidelines.html#THRESHOLDFORMAT (Threshold and ranges)
- https://nagios-plugins.org/doc/guidelines.html#AEN200 (Performance data)
- https://nagios-plugins.org/doc/guidelines.html#PLUGOPTIONS (Plugin Options)
- https://nagios-plugins.org/doc/guidelines.html#AEN302 (Option Processing)
Note: The screen output of the help page will (mostly) be limited to 80 characters width; but the max recommended length of 23 lines cannot be guaranteed.
 
This framework does currently NOT support following guidelines:
- https://nagios-plugins.org/doc/guidelines.html#AEN74 (Screen Output)
- https://nagios-plugins.org/doc/guidelines.html#AEN239 (Translations)
- https://nagios-plugins.org/doc/guidelines.html#AEN293 (Use DEFAULT_SOCKET_TIMEOUT)
- https://nagios-plugins.org/doc/guidelines.html#AEN296 (Add alarms to network plugins)
- https://nagios-plugins.org/doc/guidelines.html#AEN245 (Don't execute system commands without specifying their full path)
- https://nagios-plugins.org/doc/guidelines.html#AEN249 (Use spopen() if external commands must be executed)
- https://nagios-plugins.org/doc/guidelines.html#AEN253 (Don't make temp files unless absolutely required)
- https://nagios-plugins.org/doc/guidelines.html#AEN259 (Validate all input)
- https://nagios-plugins.org/doc/guidelines.html#AEN317 (Plugins with more than one type of threshold, or with threshold ranges)
 
We will intentionally NOT follow the following guidelines:
- https://nagios-plugins.org/doc/guidelines.html#AEN256 (Don't be tricked into following symlinks)
Reason: We believe that this guideline is contraproductive.
Nagios plugins usually run as user 'nagios'. It is the task of the system administrator
to ensure that the user 'nagios' must not read/write to files which are not intended
for access by the Nagios service. Instead, symlinks are useful for several tasks.
See also http://stackoverflow.com/questions/27112949/nagios-plugins-why-not-following-symlinks
 
VNag over HTTP:
 
A script that uses the VNag framework can run as CLI script (normal Nagios plugin) or as web site (or both).
Having the script run as website, you can include a Nagios information combined with a human friendly HTML output which can
include colors, graphics (like charts) etc.
 
For example:
A script that measures traffic can have a website which shows graphs,
and has a hidden Nagios output included, which can be read by a Nagios plugin that
converts the hidden information on that website into an output that Nagios can evaluate.
 
Here is a comparison of the usage and behavior of VNag in regards to CLI and HTTP calls:
 
------------------------------------------------------------------------------------------
CLI script HTTP script
------------------------------------------------------------------------------------------
* "echo" will be discarded. * "echo" output will be discarded.
 
* Exceptions will be handled. * Exceptions will be handled.
 
* outputHTML() will be ignored. * outputHTML() will be handled.
(This allows you to have the same script
running as CLI and HTML)
 
* Arguments are passed via CLI. * Arguments are passed via $_REQUEST
(i.e. GET or POST)
 
* Arguments: "-vvv" * Arguments: GET ?v[]=&v[]=&v[]= or POST
 
* When run() has finished, the program * When run() has finished, the program
flow continues, although it is not flow continues.
recommended that you do anything after it.
(The exit code is remembered for the
shutdown handler)
 
* Exactly 1 job must be called, resulting * You can call as many jobs as you want.
in a single output of that job. A website can include more than one
Nagios output which are enumerated with
a serial number (0,1,2,3,...) or manual ID.
------------------------------------------------------------------------------------------
 
****************************************************************************************************/
 
error_reporting(-1);
 
# If you want to use -t/--timeout with your module, you must add following line in your module code:
// WONTFIX: declare(ticks=1) is deprecated? http://www.hackingwithphp.com/4/21/0/the-declare-function-and-ticks
// WONTFIX: check is the main script used declare(ticks=1). (Not possible in PHP)
declare(ticks=1);
 
# Attention: The -t/--timeout parameter does not respect the built-in set_time_limit() of PHP.
# PHP should set this time limit to infinite.
set_time_limit(0);
 
define('VNAG_JSONDATA_V1', 'oid:1.3.6.1.4.1.37476.2.3.1.1');
 
// Set this to an array to overwrite getopt() and $_REQUEST[], respectively.
// Useful for mock tests.
$OVERWRITE_ARGUMENTS = null;
 
function _empty($x) {
if (is_array($x)) debug_print_stacktrace();
// Returns true for '' or null. Does not return true for value 0 or '0' (like empty() does)
return trim($x) == '';
}
 
abstract class VNag {
const VNAG_VERSION = '2018-10-02';
 
// Status 0..3 for STATUSMODEL_SERVICE (the default status model):
# The guideline states: "Higher-level errors (such as name resolution errors, socket timeouts, etc) are outside of the control of plugins and should generally NOT be reported as UNKNOWN states."
# We choose 4 as exitcode. The plugin developer is free to return any other status.
const STATUS_OK = 0;
const STATUS_WARNING = 1;
const STATUS_CRITICAL = 2;
const STATUS_UNKNOWN = 3;
const STATUS_ERROR = 4; // and upwards
 
// Status 0..1 for STATUSMODEL_HOST:
// The page https://blog.centreon.com/good-practices-how-to-develop-monitoring-plugin-nagios/
// states that host plugins may return following status codes:
// 0=UP, 1=DOWN, Other=Maintains last known state
const STATUS_UP = 0;
const STATUS_DOWN = 1;
const STATUS_MAINTAIN = 2; // and upwards
 
const VERBOSITY_SUMMARY = 0;
const VERBOSITY_ADDITIONAL_INFORMATION = 1;
const VERBOSITY_CONFIGURATION_DEBUG = 2;
const VERBOSITY_PLUGIN_DEBUG = 3;
const MAX_VERBOSITY = self::VERBOSITY_PLUGIN_DEBUG;
 
const STATUSMODEL_SERVICE = 0;
const STATUSMODEL_HOST = 1;
 
private $initialized = false;
 
private $status = null;
private $messages = array(); // array of messages which are all put together into the headline, comma separated
private $verbose_info = ''; // all other lines
private $warningRanges = array();
private $criticalRanges = array();
private $performanceDataObjects = array();
private static $exitcode = 0;
 
private $helpObj = null;
private $argHandler = null;
 
const OUTPUT_SPECIAL = 1; // illegal usage / help page, version page
const OUTPUT_NORMAL = 2;
const OUTPUT_EXCEPTION = 4;
const OUTPUT_ALWAYS = 7;
const OUTPUT_NEVER = 0;
 
// set to true if you want the output being shown in the HTML beside of the invisible tag
// set to false if you just want to send the invisible tag
public $http_visual_output = self::OUTPUT_ALWAYS;
public $http_invisible_output = self::OUTPUT_ALWAYS;
 
// $html_before and $html_after contain the output HTML which were sent by the user
 
// before and after the visual output
protected $html_before = '';
protected $html_after = '';
 
protected $statusmodel = self::STATUSMODEL_SERVICE;
 
protected $show_status_in_headline = true;
 
protected $default_status = self::STATUS_UNKNOWN;
protected $default_warning_range = null;
protected $default_critical_range = null;
 
protected $argWarning;
protected $argCritical;
protected $argVersion;
protected $argVerbosity;
protected $argTimeout;
protected $argHelp;
protected $argUsage;
 
// -----------------------------------------------------------
 
// The ID will be used for writing AND reading of the machine readable
// Nagios output embedded in a website. (A web-reader acts as proxy, so the
// input and output ID will be equal)
// Attention: Once you run run(), $id will be "used" and resetted to null.
// The ID can be any string, e.g. a GUID, an OID, a package name or something else.
// It should be unique. If you don't set an ID, a serial number (0, 1, 2, 3, ...) will be
// used for your outputs.
public $id = null;
protected static $http_serial_number = 0;
 
// -----------------------------------------------------------
 
// Private key: Optional feature used in writeInvisibleHTML (called by run in HTTP mode)
public $privkey = null;
public $privkey_password = null;
public $sign_algo = OPENSSL_ALGO_SHA256;
 
// Public key: Used in readInvisibleHTML
public $pubkey = null;
 
// -----------------------------------------------------------
 
// These settings should be set by derivated classes where the user intuitively expects the
// warning (w) or critical (c) parameter to mean something else than defined in the development guidelines.
// Usually, the single value "-w X" means the same like "-w X:X", which means everything except X is bad.
// This behavior is VNag::SINGLEVALUE_RANGE_DEFAULT.
// But for plugins e.g. for checking disk space, the user expects the argument "-w X" to mean
// "everything below X is bad" (if X is defined as free disk space).
// So we would choose the setting VNag::SINGLEVALUE_RANGE_VAL_LT_X_BAD.
// Note: This setting is implemented as array, so that each range number (in case you want to have more
// than one range, like in the PING plugin that checks latency and package loss)
// can have its individual behavior for single values.
protected $warningSingleValueRangeBehaviors = array(self::SINGLEVALUE_RANGE_DEFAULT);
protected $criticalSingleValueRangeBehaviors = array(self::SINGLEVALUE_RANGE_DEFAULT);
 
// Default behavior according to the development guidelines:
// x means x:x, which means, everything except x% is bad.
// @x means @x:x, which means, x is bad and everything else is good.
const SINGLEVALUE_RANGE_DEFAULT = 0;
 
// The single value x means, everything > x is bad. @x is not defined.
const SINGLEVALUE_RANGE_VAL_GT_X_BAD = 1;
 
// The single value x means, everything >= x is bad. @x is not defined.
const SINGLEVALUE_RANGE_VAL_GE_X_BAD = 2;
 
// The single value x means, everything < x is bad. @x is not defined.
const SINGLEVALUE_RANGE_VAL_LT_X_BAD = 3;
 
// The single value x means, everything <= x is bad. @x is not defined.
const SINGLEVALUE_RANGE_VAL_LE_X_BAD = 4;
 
// -----------------------------------------------------------
 
// Encryption password: Optional feature used in writeInvisibleHTML (called by run in HTTP mode)
public $password_out = null;
 
// Decryption password: Used in readInvisibleHTML to decrypt an encrypted machine readable info
public $password_in = null;
 
// -----------------------------------------------------------
 
public static function is_http_mode() {
return php_sapi_name() !== 'cli';
}
 
public function getHelpManager() {
return $this->helpObj;
}
 
public function getArgumentHandler() {
return $this->argHandler;
}
 
public function outputHTML($text, $after_visual_output=true) {
if ($this->is_http_mode()) {
if ($this->initialized) {
if ($after_visual_output) {
$this->html_after .= $text;
} else {
$this->html_before .= $text;
}
} else {
echo $text;
}
}
}
 
protected function resetArguments() {
$this->argWarning = null;
$this->argCritical = null;
$this->argVersion = null;
$this->argVerbosity = null;
$this->argTimeout = null;
$this->argHelp = null;
// $this->argUsage = null;
 
// Also remove cache
$this->warning = null;
$this->critical = null;
}
 
// e.g. $args = "wcVvht"
public function registerExpectedStandardArguments($args) {
$this->resetArguments();
 
for ($i=0; $i<strlen($args); $i++) {
switch ($args[$i]) {
case 'w':
$this->addExpectedArgument($this->argWarning = new VNagArgument('w', 'warning', VNagArgument::VALUE_REQUIRED, VNagLang::$argname_value, VNagLang::$warning_range));
break;
case 'c':
$this->addExpectedArgument($this->argCritical = new VNagArgument('c', 'critical', VNagArgument::VALUE_REQUIRED, VNagLang::$argname_value, VNagLang::$critical_range));
break;
case 'V':
$this->addExpectedArgument($this->argVersion = new VNagArgument('V', 'version', VNagArgument::VALUE_FORBIDDEN, null, VNagLang::$prints_version));
break;
case 'v':
// In HTTP: -vvv is &v[]=&v[]=&v[]=
$this->addExpectedArgument($this->argVerbosity = new VNagArgument('v', 'verbose', VNagArgument::VALUE_FORBIDDEN, null, VNagLang::$verbosity_helptext));
break;
case 't':
// Attention: not every plugin supports it because of declare(ticks=1) needs to be written in the main script
$this->addExpectedArgument($this->argTimeout = new VNagArgument('t', 'timeout', VNagArgument::VALUE_REQUIRED, VNagLang::$argname_seconds, VNagLang::$timeout_helptext));
break;
// case '?':
case 'h':
$this->addExpectedArgument($this->argHelp = new VNagArgument('h', 'help', VNagArgument::VALUE_FORBIDDEN, null, VNagLang::$help_helptext));
break;
default:
$letter = $args[$i];
throw new VNagInvalidStandardArgument(sprintf(VNagLang::$no_standard_arguments_with_letter, $letter));
break;
}
}
}
 
public function addExpectedArgument($argObj) {
// Emulate C++ "friend" access to hidden functions
 
// $this->helpObj->_addOption($argObj);
$helpObjAddEntryMethod = new ReflectionMethod($this->helpObj, '_addOption');
$helpObjAddEntryMethod->setAccessible(true);
$helpObjAddEntryMethod->invoke($this->helpObj, $argObj);
 
// $this->argHandler->_addExpectedArgument($argObj);
$argHandlerAddEntryMethod = new ReflectionMethod($this->argHandler, '_addExpectedArgument');
$argHandlerAddEntryMethod->setAccessible(true);
$argHandlerAddEntryMethod->invoke($this->argHandler, $argObj);
}
 
protected function createArgumentHandler() {
$this->argHandler = new VNagArgumentHandler();
}
 
protected function createHelpObject() {
$this->helpObj = new VNagHelp();
}
 
protected function checkInitialized() {
if (!$this->initialized) throw new VNagFunctionCallOutsideSession();
}
 
protected function getVerbosityLevel() {
$this->checkInitialized(); // if (!$this->initialized) return false;
 
if (!isset($this->argVerbosity)) {
//The verbose argument is always optional
//throw new VNagRequiredArgumentNotRegistered('-v');
return self::VERBOSITY_SUMMARY;
} else {
$level = $this->argVerbosity->count();
if ($level > self::MAX_VERBOSITY) $level = self::MAX_VERBOSITY;
return $level;
}
}
 
public function getWarningRange($argumentNumber=0) {
$this->checkInitialized(); // if (!$this->initialized) return false;
 
if (!isset($this->warningRanges[$argumentNumber])) {
if (!is_null($this->argWarning)) {
$warning = $this->argWarning->getValue();
if (!is_null($warning)) {
$vals = explode(',',$warning);
foreach ($vals as $number => $val) {
if (_empty($val)) {
$this->warningRanges[$number] = null;
} else {
$singleValueBehavior = isset($this->warningSingleValueRangeBehaviors[$number]) ? $this->warningSingleValueRangeBehaviors[$number] : VNag::SINGLEVALUE_RANGE_DEFAULT;
$this->warningRanges[$number] = new VNagRange($val, $singleValueBehavior);
}
}
} else {
$this->warningRanges[0] = $this->default_warning_range;
}
} else {
return null;
}
}
 
if (isset($this->warningRanges[$argumentNumber])) {
return $this->warningRanges[$argumentNumber];
} else {
return null;
}
}
 
public function getCriticalRange($argumentNumber=0) {
$this->checkInitialized(); // if (!$this->initialized) return false;
 
if (!isset($this->criticalRanges[$argumentNumber])) {
if (!is_null($this->argCritical)) {
$critical = $this->argCritical->getValue();
if (!is_null($critical)) {
$vals = explode(',',$critical);
foreach ($vals as $number => $val) {
$singleValueBehavior = isset($this->criticalSingleValueRangeBehaviors[$number]) ? $this->criticalSingleValueRangeBehaviors[$number] : VNag::SINGLEVALUE_RANGE_DEFAULT;
$this->criticalRanges[$number] = new VNagRange($val, $singleValueBehavior);
}
} else {
$this->criticalRanges[0] = $this->default_critical_range;
}
} else {
return null;
}
}
 
if (isset($this->criticalRanges[$argumentNumber])) {
return $this->criticalRanges[$argumentNumber];
} else {
return null;
}
}
 
public function checkAgainstWarningRange($values, $force=true, $autostatus=true, $argumentNumber=0) {
$this->checkInitialized(); // if (!$this->initialized) return;
 
if (!$this->getArgumentHandler()->isArgRegistered('w')) {
// Developer's mistake: The argument is not in the list of expected arguments
throw new VNagRequiredArgumentNotRegistered('-w');
}
 
$wr = $this->getWarningRange($argumentNumber);
if (isset($wr)) {
if ($wr->checkAlert($values)) {
if ($autostatus) $this->setStatus(VNag::STATUS_WARNING);
return true;
} else {
if ($autostatus) $this->setStatus(VNag::STATUS_OK);
return false;
}
} else {
if ($force) {
// User's mistake: They did not pass the argument to the plugin
if (($argumentNumber > 0) && (count($this->warningRanges) > 0)) {
throw new VNagInvalidArgumentException(sprintf(VNagLang::$too_few_warning_ranges, $argumentNumber+1));
} else {
throw new VNagRequiredArgumentMissing('-w');
}
}
}
}
 
public function checkAgainstCriticalRange($values, $force=true, $autostatus=true, $argumentNumber=0) {
$this->checkInitialized(); // if (!$this->initialized) return;
 
if (!$this->getArgumentHandler()->isArgRegistered('c')) {
// Developer's mistake: The argument is not in the list of expected arguments
throw new VNagRequiredArgumentNotRegistered('-c');
}
 
$cr = $this->getCriticalRange($argumentNumber);
if (isset($cr)) {
if ($cr->checkAlert($values)) {
if ($autostatus) $this->setStatus(VNag::STATUS_CRITICAL);
return true;
} else {
if ($autostatus) $this->setStatus(VNag::STATUS_OK);
return false;
}
} else {
if ($force) {
// User's mistake: They did not pass the argument to the plugin
if (($argumentNumber > 0) && (count($this->warningRanges) > 0)) {
throw new VNagInvalidArgumentException(sprintf(VNagLang::$too_few_critical_ranges, $argumentNumber+1));
} else {
throw new VNagRequiredArgumentMissing('-c');
}
}
}
}
 
protected static function getBaddestExitcode($code1, $code2) {
return max($code1, $code2);
}
 
# DO NOT CALL MANUALLY
# Unfortunately, this function has to be public, otherwise register_shutdown_function() wouldn't work
public static function _shutdownHandler() {
if (!self::is_http_mode()) {
exit((int)self::$exitcode);
}
}
 
protected function _exit($code) {
self::$exitcode = $this->getBaddestExitcode($code, self::$exitcode);
}
 
private $constructed = false;
function __construct() {
$this->createHelpObject();
$this->createArgumentHandler();
 
$this->addExpectedArgument($this->argUsage = new VNagArgument('?', '', VNagArgument::VALUE_FORBIDDEN, null, VNagLang::$prints_usage));
 
$this->constructed = true;
}
 
function __destruct() {
if (Timeouter::started()) {
Timeouter::end();
}
}
 
// $optional_args will be forwarded to the callback function cbRun()
public function run($optional_args=array()) {
if (!$this->constructed) {
throw new VNagNotConstructed(VNagLang::$notConstructed);
}
 
try {
$this->initialized = true;
$this->html_before = '';
$this->html_after = '';
$this->setStatus(null, true);
$this->messages = array();
 
register_shutdown_function(array($this, '_shutdownHandler'));
 
if ($this->argHandler->illegalUsage()) {
$content = $this->helpObj->printUsagePage();
$this->setStatus(VNag::STATUS_UNKNOWN);
 
if ($this->is_http_mode()) {
echo $this->html_before;
if ($this->http_visual_output & VNag::OUTPUT_SPECIAL) echo $this->writeVisualHTML($content);
if ($this->http_invisible_output & VNag::OUTPUT_SPECIAL) echo $this->writeInvisibleHTML($content);
echo $this->html_after;
return; // cancel
} else {
echo $content;
return $this->_exit($this->status);
}
}
 
if (!is_null($this->argVersion) && ($this->argVersion->available())) {
$content = $this->helpObj->printVersionPage();
$this->setStatus(VNag::STATUS_UNKNOWN);
 
if ($this->is_http_mode()) {
echo $this->html_before;
if ($this->http_visual_output & VNag::OUTPUT_SPECIAL) echo $this->writeVisualHTML($content);
if ($this->http_invisible_output & VNag::OUTPUT_SPECIAL) echo $this->writeInvisibleHTML($content);
echo $this->html_after;
return; // cancel
} else {
echo $content;
return $this->_exit($this->status);
}
}
 
if (!is_null($this->argHelp) && ($this->argHelp->available())) {
$content = $this->helpObj->printHelpPage();
$this->setStatus(VNag::STATUS_UNKNOWN);
 
if ($this->is_http_mode()) {
echo $this->html_before;
if ($this->http_visual_output & VNag::OUTPUT_SPECIAL) echo $this->writeVisualHTML($content);
if ($this->http_invisible_output & VNag::OUTPUT_SPECIAL) echo $this->writeInvisibleHTML($content);
echo $this->html_after;
return; // cancel
} else {
echo $content;
return $this->_exit($this->status);
}
}
 
// Initialize ranges (and check their validity)
$this->getWarningRange();
$this->getCriticalRange();
 
if (!is_null($this->argTimeout)) {
$timeout = $this->argTimeout->getValue();
if (!is_null($timeout)) {
Timeouter::start($timeout);
}
}
 
ob_start();
$init_ob_level = ob_get_level();
try {
$this->cbRun($optional_args);
 
// This will NOT be put in the 'finally' block, because otherwise it would trigger if an Exception happened (Which clears the OB)
if (ob_get_level() < $init_ob_level) throw new VNagImplementationErrorException(VNagLang::$output_level_lowered);
} finally {
while (ob_get_level() > $init_ob_level) @ob_end_clean();
}
 
if (is_null($this->status)) $this->setStatus($this->default_status,true);
 
$outputType = VNag::OUTPUT_NORMAL;
} catch (Exception $e) {
$this->handleException($e);
$outputType = VNag::OUTPUT_EXCEPTION;
}
 
if ($this->is_http_mode()) {
echo $this->html_before;
if ($this->http_invisible_output & $outputType) {
echo $this->writeInvisibleHTML();
}
if ($this->http_visual_output & $outputType) {
echo $this->writeVisualHTML();
}
echo $this->html_after;
} else {
echo $this->getNagiosConsoleText();
return $this->_exit($this->status);
}
 
Timeouter::end();
}
 
private function getNagiosConsoleText() {
// see https://nagios-plugins.org/doc/guidelines.html#AEN200
// 1. space separated list of label/value pairs
$ary_perfdata = $this->getPerformanceData();
$performancedata_first = array_shift($ary_perfdata);
$performancedata_rest = implode(' ', $ary_perfdata);
 
$status_text = VNagLang::status($this->status, $this->statusmodel);
if (_empty($this->getHeadline())) {
$content = $status_text;
} else {
if ($this->show_status_in_headline) {
$content = $status_text.': '.$this->getHeadline();
} else {
$content = $this->getHeadline();
}
}
 
if (!_empty($performancedata_first)) $content .= '|'.trim($performancedata_first);
$content .= "\n";
if (!_empty($this->verbose_info)) {
//$content .= "\n".VNagLang::$verbose_info.":\n\n";
$content .= trim($this->verbose_info);
}
if (!_empty($performancedata_rest)) $content .= '|'.trim($performancedata_rest);
$content .= "\n";
 
return trim($content)."\n";
}
 
abstract protected function cbRun();
 
public function addPerformanceData($prefDataObj, $move_to_font=false, $verbosityLevel=VNag::VERBOSITY_SUMMARY) {
$this->checkInitialized(); // if (!$this->initialized) return;
 
if ((!isset($this->argVerbosity)) && ($verbosityLevel > VNag::VERBOSITY_SUMMARY)) throw new VNagRequiredArgumentNotRegistered('-v');
if (self::getVerbosityLevel() < $verbosityLevel) return false;
 
if ($move_to_font) {
array_unshift($this->performanceDataObjects, $prefDataObj);
} else {
$this->performanceDataObjects[] = $prefDataObj;
}
 
return true;
}
 
public function getPerformanceData() {
$this->checkInitialized(); // if (!$this->initialized) return null;
 
// see https://nagios-plugins.org/doc/guidelines.html#AEN200
// 1. space separated list of label/value pairs
return $this->performanceDataObjects;
}
 
public function removePerformanceData($prefDataObj) {
if (($key = array_search($prefDataObj, $this->performanceDataObjects, true)) !== false) {
unset($this->performanceDataObjects[$key]);
return true;
} else {
return false;
}
}
 
public function clearPerformanceData() {
$this->performanceDataObjects = array();
}
 
public function getVerboseInfo() {
return $this->verbose_info;
}
 
public function clearVerboseInfo() {
$this->verbose_info = '';
}
 
private function writeVisualHTML($special_content=null) {
if (!_empty($special_content)) {
$content = $special_content;
} else {
$content = strtoupper(VNagLang::$status.': '.VNagLang::status($this->status, $this->statusmodel))."\n\n";
 
$content .= strtoupper(VNagLang::$message).":\n";
$status_text = VNagLang::status($this->status, $this->statusmodel);
if (_empty($this->getHeadline())) {
$content .= $status_text;
} else {
if ($this->show_status_in_headline) {
$content .= $status_text.': '.trim($this->getHeadline());
} else {
$content .= trim($this->getHeadline());
}
}
$content .= "\n\n";
 
if (!_empty($this->verbose_info)) {
$content .= strtoupper(VNagLang::$verbose_info).":\n".trim($this->verbose_info)."\n\n";
}
 
$perfdata = $this->getPerformanceData();
if (count($perfdata) > 0) {
$content .= strtoupper(VNagLang::$performance_data).":\n";
foreach ($perfdata as $pd) {
$content .= trim($pd)."\n";
}
$content .= "\n";
}
}
 
$colorinfo = '';
$status = $this->getStatus();
 
if ($status == VNag::STATUS_OK) $colorinfo = ' style="background-color:green;color:white;font-weight:bold"';
else if ($status == VNag::STATUS_WARNING) $colorinfo = ' style="background-color:yellow;color:black;font-weight:bold"';
else if ($status == VNag::STATUS_CRITICAL) $colorinfo = ' style="background-color:red;color:white;font-weight:bold"';
else if ($status == VNag::STATUS_ERROR) $colorinfo = ' style="background-color:purple;color:white;font-weight:bold"';
else /* if ($status == VNag::STATUS_UNKNOWN) */ $colorinfo = ' style="background-color:lightgray;color:black;font-weight:bold"';
 
$html_content = trim($content);
$html_content = htmlentities($html_content);
$html_content = str_replace(' ', '&nbsp;', $html_content);
$html_content = nl2br($html_content);
 
// FUT: Allow individual design via CSS
return '<table border="1" cellspacing="2" cellpadding="2" style="width:100%" class="vnag_table">'.
'<tr'.$colorinfo.' class="vnag_title_row">'.
'<td>'.VNagLang::$nagios_output.'</td>'.
'</tr>'.
'<tr class="vnag_message_row">'.
'<td><code>'.
$html_content.
'</code></td>'.
'</tr>'.
'</table>';
}
 
protected function readInvisibleHTML($html) {
$this->checkInitialized(); // if (!$this->initialized) return;
 
$doc = new DOMDocument(); // Requires: aptitude install php-dom
@$doc->loadHTML($html); // added '@' because we don't want a warning for the non-standard <vnag> tag
 
$tags = $doc->getElementsByTagName('script');
foreach ($tags as $tag) {
$type = $tag->getAttribute('type');
if ($type !== 'application/json') continue;
 
$json = $tag->nodeValue;
if (!$json) continue;
 
$data = @json_decode($json,true);
if (!is_array($data)) continue;
 
if (!isset($data['type'])) continue;
if ($data['type'] === VNAG_JSONDATA_V1) {
if (!isset($data['datasets'])) throw new VNagWebInfoException(VNagLang::$dataset_missing);
foreach ($data['datasets'] as $dataset) {
$payload = base64_decode($dataset['payload']);
if (!$payload) {
throw new VNagWebInfoException(VNagLang::$payload_not_base64);
}
 
if (isset($dataset['encryption'])) {
// The dataset is encrypted. We need to decrypt it first.
 
$cryptInfo = $dataset['encryption'];
if (!is_array($cryptInfo)) {
throw new VNagWebInfoException(VNagLang::$dataset_encryption_no_array);
}
 
$password = is_null($this->password_in) ? '' : $this->password_in;
 
$salt = base64_decode($cryptInfo['salt']);
 
if ($cryptInfo['hash'] != hash('sha256',$salt.$password)) {
if ($password == '') {
throw new VNagWebInfoException(VNagLang::$require_password);
} else {
throw new VNagWebInfoException(VNagLang::$wrong_password);
}
}
 
$payload = openssl_decrypt($payload, $cryptInfo['method'], $password, 0, $cryptInfo['iv']);
}
 
if (!is_null($this->pubkey)) {
if (!file_exists($this->pubkey)) {
throw new VNagInvalidArgumentException(sprintf(VNagLang::$pubkey_file_not_found, $this->pubkey));
}
 
$public_key = @file_get_contents($this->pubkey);
if (!$public_key) {
throw new VNagPublicKeyException(sprintf(VNagLang::$pubkey_file_not_readable, $this->pubkey));
}
 
if (!isset($dataset['signature'])) {
throw new VNagSignatureException(VNagLang::$signature_missing);
}
 
$signature = base64_decode($dataset['signature']);
if (!$signature) {
throw new VNagSignatureException(VNagLang::$signature_not_bas64);
}
 
if (!openssl_verify($payload, $signature, $public_key, $this->sign_algo)) {
throw new VNagSignatureException(VNagLang::$signature_invalid);
}
}
 
$payload = @json_decode($payload,true);
if (!$payload) {
throw new VNagWebInfoException(VNagLang::$payload_not_json);
}
 
if ($payload['id'] == $this->id) {
return $payload;
}
}
}
}
 
return null;
}
 
private function getNextMonitorID($peek=false) {
$result = is_null($this->id) ? self::$http_serial_number : $this->id;
 
if (!$peek) {
$this->id = null; // use manual ID only once
self::$http_serial_number++;
}
 
return $result;
}
 
private function writeInvisibleHTML($special_content=null) {
// 1. Create the payload
 
$payload['id'] = $this->getNextMonitorID();
 
$payload['status'] = $this->getStatus();
 
if (!_empty($special_content)) {
$payload['text'] = $special_content;
} else {
$payload['headline'] = $this->getHeadline();
$payload['verbose_info'] = $this->verbose_info;
 
$payload['performance_data'] = array();
foreach ($this->performanceDataObjects as $perfdata) {
$payload['performance_data'][] = (string)$perfdata;
}
}
 
$payload = json_encode($payload);
 
// 2. Encode the payload as JSON and optionally sign and/or encrypt it
 
$dataset = array();
 
if (!is_null($this->privkey)) {
if (!file_exists($this->privkey)) {
throw new VNagInvalidArgumentException(sprintf(VNagLang::$privkey_file_not_found, $this->privkey));
}
$pkeyid = @openssl_pkey_get_private('file://'.$this->privkey, $privkey_password);
if (!$pkeyid) {
throw new VNagPrivateKeyException(sprintf(VNagLang::$privkey_file_not_readable, $this->privkey));
}
 
openssl_sign($payload, $signature, $pkeyid, $this->sign_algo);
openssl_free_key($pkeyid);
 
$dataset['signature'] = base64_encode($signature);
}
 
if (!is_null($this->password_out)) {
$password = $this->password_out;
 
$method = 'aes-256-ofb';
$iv = substr(hash('sha256', openssl_random_pseudo_bytes(32)), 0, 16);
$salt = openssl_random_pseudo_bytes(32);
 
$cryptInfo = array();
$cryptInfo['method'] = $method;
$cryptInfo['iv'] = $iv;
$cryptInfo['salt'] = base64_encode($salt);
$cryptInfo['hash'] = hash('sha256', $salt.$password);
 
$payload = openssl_encrypt($payload, $method, $password, 0, $iv);
$dataset['encryption'] = $cryptInfo;
}
 
$dataset['payload'] = base64_encode($payload);
 
// 3. Encode everything as JSON+Base64 (again) and put it into the data block
 
$json = array();
$json['type'] = VNAG_JSONDATA_V1;
$json['datasets'] = array($dataset); // we only output 1 dataset. We could technically output more than one into this data block.
 
// Include the machine readable information as data block
// This method was chosen to support HTML 4.01, XHTML and HTML5 as well without breaking the standards
// see https://stackoverflow.com/questions/51222713/using-an-individual-tag-without-breaking-the-standards/51223609#51223609
return '<script type="application/json">'.
json_encode($json).
'</script>';
}
 
protected function appendHeadline($msg) {
$this->checkInitialized(); // if (!$this->initialized) return;
 
if (_empty($msg)) return false;
$this->messages[] = $msg;
 
return true;
}
 
protected function changeHeadline($msg) {
$this->checkInitialized(); // if (!$this->initialized) return;
 
if (_empty($msg)) {
$this->messages = array();
} else {
$this->messages = array($msg);
}
 
return true;
}
 
public function setHeadline($msg, $append=false, $verbosityLevel=VNag::VERBOSITY_SUMMARY) {
$this->checkInitialized(); // if (!$this->initialized) return;
 
if ((!isset($this->argVerbosity)) && ($verbosityLevel > VNag::VERBOSITY_SUMMARY)) throw new VNagRequiredArgumentNotRegistered('-v');
if (self::getVerbosityLevel() < $verbosityLevel) $msg = '';
 
if ($append) {
return $this->appendHeadline($msg);
} else {
return $this->changeHeadline($msg);
}
}
 
public function getHeadline() {
$this->checkInitialized(); // if (!$this->initialized) return '';
 
return implode(', ', $this->messages);
}
 
public function addVerboseMessage($msg, $verbosityLevel=VNag::VERBOSITY_SUMMARY) {
$this->checkInitialized(); // if (!$this->initialized) return;
 
if (self::getVerbosityLevel() >= $verbosityLevel) {
$this->verbose_info .= $msg."\n";
}
}
 
public function setStatus($status, $force=false) {
$this->checkInitialized(); // if (!$this->initialized) return;
 
if (($force) || is_null($this->status) || ($status > $this->status)) {
$this->status = $status;
}
}
 
public function getStatus() {
$this->checkInitialized(); // if (!$this->initialized) return;
 
return $this->status;
}
 
protected static function exceptionText($exception) {
// $this->checkInitialized(); // if (!$this->initialized) return false;
 
$class = get_class($exception);
$msg = $exception->getMessage();
 
if (!_empty($msg)) {
return sprintf(VNagLang::$exception_x, $msg, $class);
} else {
return sprintf(VNagLang::$unhandled_exception_without_msg, $class);
}
}
 
protected function handleException($exception) {
$this->checkInitialized(); // if (!$this->initialized) return;
 
while (ob_get_level() > 0) @ob_end_clean();
$this->clearVerboseInfo();
$this->clearPerformanceData();
 
if ($exception instanceof VNagException) {
$this->setStatus($exception->getStatus());
} else {
$this->setStatus(self::STATUS_ERROR);
}
 
$this->setHeadline($this->exceptionText($exception), false);
 
if ($exception instanceof VNagImplementationException) {
$this->addVerboseMessage($exception->getTraceAsString(), VNag::VERBOSITY_SUMMARY);
} else {
if (isset($this->argVerbosity)) {
$this->addVerboseMessage($exception->getTraceAsString(), VNag::VERBOSITY_ADDITIONAL_INFORMATION);
} else {
// $this->addVerboseMessage($exception->getTraceAsString(), VNag::VERBOSITY_SUMMARY);
}
}
}
}
 
 
class VNagException extends Exception {
public function getStatus() {
return VNag::STATUS_ERROR;
}
}
 
class VNagTimeoutException extends VNagException {}
 
class VNagWebInfoException extends VNagException {}
class VNagSignatureException extends VNagException {}
class VNagPublicKeyException extends VNagException {}
class VNagPrivateKeyException extends VNagException {}
 
// VNagInvalidArgumentException are exceptions which result from a wrong use
// of arguments by the USER (CLI arguments or HTTP parameters)
class VNagInvalidArgumentException extends VNagException {
public function getStatus() {
return VNag::STATUS_UNKNOWN;
}
}
 
class VNagValueUomPairSyntaxException extends VNagInvalidArgumentException {
public function __construct($str) {
$e_msg = sprintf(VNagLang::$valueUomPairSyntaxError, $str);
parent::__construct($e_msg);
}
}
 
class VNagInvalidTimeoutException extends VNagInvalidArgumentException {}
 
class VNagInvalidRangeException extends VNagInvalidArgumentException {
public function __construct($msg) {
$e_msg = VNagLang::$range_is_invalid;
if (!_empty($msg)) $e_msg .= ': '.trim($msg);
parent::__construct($e_msg);
}
}
 
class VNagInvalidShortOpt extends VNagImplementationErrorException {}
class VNagInvalidLongOpt extends VNagImplementationErrorException {}
class VNagInvalidValuePolicy extends VNagImplementationErrorException {}
class VNagIllegalStatusModel extends VNagImplementationErrorException {}
class VNagNotConstructed extends VNagImplementationErrorException {}
 
// To enforce that people use the API correctly, we report flaws in the implementation
// as Exception.
class VNagImplementationErrorException extends VNagException {}
 
class VNagInvalidStandardArgument extends VNagImplementationErrorException {}
class VNagFunctionCallOutsideSession extends VNagImplementationErrorException {}
class VNagIllegalArgumentValuesException extends VNagImplementationErrorException {}
 
class VNagRequiredArgumentNotRegistered extends VNagImplementationErrorException {
// Developer's mistake: The argument is not in the list of expected arguments
public function __construct($required_argument) {
$e_msg = sprintf(VNagLang::$query_without_expected_argument, $required_argument);
parent::__construct($e_msg);
}
}
 
class VNagRequiredArgumentMissing extends VNagInvalidArgumentException {
// User's mistake: They did not pass the argument to the plugin
public function __construct($required_argument) {
$e_msg = sprintf(VNagLang::$required_argument_missing, $required_argument);
parent::__construct($e_msg);
}
}
 
class VNagUnknownUomException extends VNagInvalidArgumentException {
public function __construct($uom) {
$e_msg = sprintf(VNagLang::$perfdata_uom_not_recognized, $uom);
parent::__construct($e_msg);
}
}
 
class VNagNoCompatibleRangeUomFoundException extends VNagException {}
 
class VNagMixedUomsNotImplemented extends VNagInvalidArgumentException {
public function __construct($uom1, $uom2) {
if (_empty($uom1)) $uom1 = VNagLang::$none;
if (_empty($uom2)) $uom2 = VNagLang::$none;
$e_msg = sprintf(VNagLang::$perfdata_mixed_uom_not_implemented, $uom1, $uom2);
parent::__construct($e_msg);
}
}
 
class VNagUomConvertException extends VNagInvalidArgumentException {
// It is unknown where the invalid UOM that was passed to the normalize() function came from,
// so it is not clear what parent this Exception class should have...
// If the value comes from the developer: VNagImplementationErrorException
// If the value came from the user: VNagInvalidArgumentException
 
public function __construct($uom1, $uom2) {
if (_empty($uom1)) $uom1 = VNagLang::$none;
if (_empty($uom2)) $uom2 = VNagLang::$none;
$e_msg = sprintf(VNagLang::$convert_x_y_error, $uom1, $uom2);
parent::__construct($e_msg);
}
}
 
class VNagInvalidPerformanceDataException extends VNagInvalidArgumentException {
public function __construct($msg) {
$e_msg = VNagLang::$performance_data_invalid;
if (!_empty($msg)) $e_msg .= ': '.trim($msg);
parent::__construct($e_msg);
}
}
 
class Timeouter {
// based on http://stackoverflow.com/questions/7493676/detecting-a-timeout-for-a-block-of-code-in-php
 
private static $start_time = false;
private static $timeout;
private static $fired = false;
private static $registered = false;
 
private function __construct() {
}
 
public static function start($timeout) {
if (!is_numeric($timeout) || ($timeout <= 0)) {
throw new VNagInvalidTimeoutException(sprintf(VNagLang::$timeout_value_invalid, $timeout));
}
 
self::$start_time = microtime(true);
self::$timeout = (float) $timeout;
self::$fired = false;
if (!self::$registered) {
self::$registered = true;
register_tick_function(array('Timeouter', 'tick'));
}
}
 
public static function started() {
return self::$registered;
}
 
public static function end() {
if (self::$registered) {
unregister_tick_function(array('Timeouter', 'tick'));
self::$registered = false;
}
}
 
public static function tick() {
if ((!self::$fired) && ((microtime(true) - self::$start_time) > self::$timeout)) {
self::$fired = true; // do not fire again
throw new VNagTimeoutException(VNagLang::$timeout_exception);
}
}
}
 
class VNagArgument {
const VALUE_FORBIDDEN = 0;
const VALUE_REQUIRED = 1;
const VALUE_OPTIONAL = 2;
 
protected $shortopt;
protected $longopts;
protected $valuePolicy;
protected $valueName;
protected $helpText;
protected $defaultValue = null;
 
protected static $all_short = '';
protected static $all_long = array();
 
public function getShortOpt() {
return $this->shortopt;
}
 
public function getLongOpts() {
return $this->longopts;
}
 
public function getValuePolicy() {
return $this->valuePolicy;
}
 
public function getValueName() {
return $this->valueName;
}
 
public function getHelpText() {
return $this->helpText;
}
 
static private function validateShortOpt($shortopt) {
return preg_match('@^[a-zA-Z0-9\\+\\-\\?]$@', $shortopt, $m);
}
 
static private function validateLongOpt($longopt) {
// FUT: Check if this is accurate
return preg_match('@^[a-zA-Z0-9\\+\\-\\?]+$@', $longopt, $m);
}
 
// Note: Currently, we do not support following:
// 1. How many times may a value be defined (it needs to be manually described in $helpText)
// 2. Is this argument mandatory? (No exception will be thrown if the plugin will be started without this argument)
public function __construct($shortopt, $longopts, $valuePolicy, $valueName, $helpText, $defaultValue=null) {
// Check if $valueName is defined correctly in regards to the policy $valuePolicy
switch ($valuePolicy) {
case VNagArgument::VALUE_FORBIDDEN:
if (!_empty($valueName)) {
throw new VNagImplementationErrorException(sprintf(VNagLang::$value_name_forbidden));
}
break;
case VNagArgument::VALUE_REQUIRED:
if (_empty($valueName)) {
throw new VNagImplementationErrorException(sprintf(VNagLang::$value_name_required));
}
break;
case VNagArgument::VALUE_OPTIONAL:
if (_empty($valueName)) {
throw new VNagImplementationErrorException(sprintf(VNagLang::$value_name_required));
}
break;
default:
throw new VNagInvalidValuePolicy(sprintf(VNagLang::$illegal_valuepolicy, $valuePolicy));
}
 
// We'll check: Does the shortopt contain illegal characters?
// http://stackoverflow.com/questions/28522387/which-chars-are-valid-shortopts-for-gnu-getopt
// We do not filter +, - and ?, since we might need it for other methods, e.g. VNagArgumentHandler::_addExpectedArgument
if (!_empty($shortopt)) {
if (!self::validateShortOpt($shortopt)) {
throw new VNagInvalidShortOpt(sprintf(VNagLang::$illegal_shortopt, $shortopt));
}
}
 
if (is_array($longopts)) { // $longopts is an array
if (!is_null($longopts)) {
foreach ($longopts as $longopt) {
if (!self::validateLongOpt($longopt)) {
throw new VNagInvalidLongOpt(sprintf(VNagLang::$illegal_longopt, $longopt));
}
}
}
} else if (!_empty($longopts)) { // $longopts is a string
if (!self::validateLongOpt($longopts)) {
throw new VNagInvalidLongOpt(sprintf(VNagLang::$illegal_longopt, $longopts));
}
$longopts = array($longopts);
} else {
$longopts = array();
}
 
# valuePolicy must be between 0..2 and being int
switch ($valuePolicy) {
case VNagArgument::VALUE_FORBIDDEN:
$policyApdx = '';
break;
case VNagArgument::VALUE_REQUIRED:
$policyApdx = ':';
break;
case VNagArgument::VALUE_OPTIONAL:
$policyApdx = '::';
break;
default:
throw new VNagInvalidValuePolicy(sprintf(VNagLang::$illegal_valuepolicy, $valuePolicy));
}
 
if ((!is_null($shortopt)) && ($shortopt != '?')) self::$all_short .= $shortopt.$policyApdx;
if (!is_null($longopts)) {
foreach ($longopts as $longopt) {
self::$all_long[] = $longopt.$policyApdx;
}
}
 
$this->shortopt = $shortopt;
$this->longopts = $longopts;
$this->valuePolicy = $valuePolicy;
$this->valueName = $valueName;
$this->helpText = $helpText;
$this->defaultValue = $defaultValue;
}
 
protected static function getOptions() {
// Attention: In PHP 5.6.19-0+deb8u1 (cli), $_REQUEST is always set, so we need is_http_mode() instead of isset($_REQUEST)!
global $OVERWRITE_ARGUMENTS;
 
if (!is_null($OVERWRITE_ARGUMENTS)) {
return $OVERWRITE_ARGUMENTS;
} else if (VNag::is_http_mode()) {
return $_REQUEST;
} else {
return getopt(self::$all_short, self::$all_long);
}
}
 
public function count() {
$options = self::getOptions();
 
$count = 0;
 
if (isset($options[$this->shortopt])) {
if (is_array($options[$this->shortopt])) {
// e.g. -vvv
$count += count($options[$this->shortopt]);
} else {
// e.g. -v
$count += 1;
}
}
 
if (!is_null($this->longopts)) {
foreach ($this->longopts as $longopt) {
if (isset($options[$longopt])) {
if (is_array($options[$longopt])) {
// e.g. --verbose --verbose --verbose
$count += count($options[$longopt]);
} else {
// e.g. --verbose
$count += 1;
}
}
}
}
 
return $count;
}
 
public function available() {
$options = self::getOptions();
 
if (isset($options[$this->shortopt])) return true;
if (!is_null($this->longopts)) {
foreach ($this->longopts as $longopt) {
if (isset($options[$longopt])) return true;
}
}
return false;
}
 
public function require() {
if (!$this->available() && is_null($this->defaultValue)) {
$opt = $this->shortopt;
$opt = !_empty($opt) ? '-'.$opt : (isset($this->longopts[0]) ? '--'.$this->longopts[0] : '?');
throw new VNagRequiredArgumentMissing($opt);
}
}
 
public function getValue() {
$options = self::getOptions();
 
if (isset($options[$this->shortopt])) {
$x = $options[$this->shortopt];
if (is_array($x) && (count($x) <= 1)) $options[$this->shortopt] = $options[$this->shortopt][0];
return $options[$this->shortopt];
}
 
if (!is_null($this->longopts)) {
foreach ($this->longopts as $longopt) {
if (isset($options[$longopt])) {
$x = $options[$longopt];
if (is_array($x) && (count($x) <= 1)) $options[$longopt] = $options[$longopt][0];
return $options[$longopt];
}
}
}
 
return $this->defaultValue;
}
}
 
class VNagArgumentHandler {
protected $expectedArgs = array();
 
// Will be called by VNag via ReflectionMethod (like C++ style friends), because it should not be called manually.
// Use VNag's function instead (since it adds to the helpObj too)
protected function _addExpectedArgument($argObj) {
// -? is always illegal, so it will trigger illegalUsage(). So we don't add it to the list of
// expected arguments, otherwise illegalUsage() would be true.
if ($argObj->getShortOpt() == '?') return false;
 
// GNU extensions with a special meaning
if ($argObj->getShortOpt() == '-') return false; // cancel parsing
if ($argObj->getShortOpt() == '+') return false; // enable POSIXLY_CORRECT
 
$this->expectedArgs[] = $argObj;
return true;
}
 
public function getArgumentObj($shortopt) {
foreach ($this->expectedArgs as $argObj) {
if ($argObj->getShortOpt() == $shortopt) return $argObj;
}
return null;
}
 
public function isArgRegistered($shortopt) {
return !is_null($this->getArgumentObj($shortopt));
}
 
public function illegalUsage() {
// In this function, we should check if $argv (resp. getopts) contains stuff which is not expected or illegal,
// so the script can show an usage information and quit the program.
 
// WONTFIX: PHP's horrible implementation of GNU's getopt does not allow following intended tasks:
// - check for illegal values/arguments (e.g. the argument -? which is always illegal)
// - check for missing values (e.g. -H instead of -H localhost )
// - check for unexpected arguments (e.g. -x if only -a -b -c are defined in $expectedArgs as expected arguments)
// - Of course, everything behind "--" may not be evaluated
// see also http://stackoverflow.com/questions/25388130/catch-unexpected-options-with-getopt
 
// So the only way is to do this stupid hard coded check for '-?'
// PHP sucks...
global $argv;
return (isset($argv[1])) && (($argv[1] == '-?') || ($argv[1] == '/?'));
}
}
 
class VNagRange {
// see https://nagios-plugins.org/doc/guidelines.html#THRESHOLDFORMAT
// We allow UOMs inside the range definition, e.g. "-w @10M:50M"
 
public /*VNagValueUomPair|'inf'*/ $start;
public /*VNagValueUomPair|'inf'*/ $end;
public /*boolean*/ $warnInsideRange;
 
public function __construct($rangeDef, $singleValueBehavior=VNag::SINGLEVALUE_RANGE_DEFAULT) {
//if (!preg_match('|(@){0,1}(\d+)(:){0,1}(\d+){0,1}|', $rangeDef, $m)) {
if (!preg_match('|^(@){0,1}([^:]+)(:){0,1}(.*)$|', $rangeDef, $m)) {
throw new VNagInvalidRangeException(sprintf(VNagLang::$range_invalid_syntax, $rangeDef));
}
 
$this->warnInsideRange = $m[1] === '@';
 
$this->start = null;
$this->end = null;
 
if ($m[3] === ':') {
if ($m[2] === '~') {
$this->start = 'inf';
} else {
$this->start = new VNagValueUomPair($m[2]);
}
 
if (_empty($m[4])) {
$this->end = 'inf';
} else {
$this->end = new VNagValueUomPair($m[4]);
}
} else {
assert(_empty($m[4]));
assert(!_empty($m[2]));
 
$x = $m[2];
 
if ($singleValueBehavior == VNag::SINGLEVALUE_RANGE_DEFAULT) {
// Default behavior according to the development guidelines:
// x means x:x, which means, everything except x% is bad.
// @x means @x:x, which means, x is bad and everything else is good.
$this->start = new VNagValueUomPair($x);
$this->end = new VNagValueUomPair($x);
} else if ($singleValueBehavior == VNag::SINGLEVALUE_RANGE_VAL_GT_X_BAD) {
// The single value x means, everything > x is bad. @x is not defined.
if ($this->warnInsideRange) throw new VNagInvalidRangeException(VNagLang::$singlevalue_unexpected_at_symbol);
$this->warnInsideRange = 0;
$this->start = 'inf';
$this->end = new VNagValueUomPair($x);
} else if ($singleValueBehavior == VNag::SINGLEVALUE_RANGE_VAL_GE_X_BAD) {
// The single value x means, everything >= x is bad. @x is not defined.
if ($this->warnInsideRange) throw new VNagInvalidRangeException(VNagLang::$singlevalue_unexpected_at_symbol);
$this->warnInsideRange = 1;
$this->start = new VNagValueUomPair($x);
$this->end = 'inf';
} else if ($singleValueBehavior == VNag::SINGLEVALUE_RANGE_VAL_LT_X_BAD) {
// The single value x means, everything < x is bad. @x is not defined.
if ($this->warnInsideRange) throw new VNagInvalidRangeException(VNagLang::$singlevalue_unexpected_at_symbol);
$this->warnInsideRange = 0;
$this->start = new VNagValueUomPair($x);
$this->end = 'inf';
} else if ($singleValueBehavior == VNag::SINGLEVALUE_RANGE_VAL_LE_X_BAD) {
// The single value x means, everything <= x is bad. @x is not defined.
if ($this->warnInsideRange) throw new VNagInvalidRangeException(VNagLang::$singlevalue_unexpected_at_symbol);
$this->warnInsideRange = 1;
$this->start = 'inf';
$this->end = new VNagValueUomPair($x);
} else {
throw new VNagException(VNagLang::$illegalSingleValueBehavior);
}
}
 
// Check if range is valid
if (is_null($this->start)) {
throw new VNagInvalidRangeException(VNagLang::$invalid_start_value);
}
if (is_null($this->end)) {
throw new VNagInvalidRangeException(VNagLang::$invalid_end_value);
}
if (($this->start instanceof VNagValueUomPair) && ($this->end instanceof VNagValueUomPair) &&
(VNagValueUomPair::compare($this->start,$this->end) > 0)) {
throw new VNagInvalidRangeException(VNagLang::$start_is_greater_than_end);
}
}
 
public function __toString() {
// Attention:
// - this function assumes that $start and $end are valid.
// - not the shortest result will be chosen
 
$ret = '';
if ($this->warnInsideRange) {
$ret = '@';
}
 
if ($this->start === 'inf') {
$ret .= '~';
} else {
$ret .= $this->start;
}
 
$ret .= ':';
 
if ($this->end !== 'inf') {
$ret .= $this->end;
}
 
return $ret;
}
 
public function checkAlert($values) {
$compatibleCount = 0;
 
if (!is_array($values)) $values = array($values);
foreach ($values as $value) {
if (!($value instanceof VNagValueUomPair)) $value = new VNagValueUomPair($value);
 
assert($this->start instanceof VNagValueUomPair);
assert($this->end instanceof VNagValueUomPair);
 
if (($this->start !== 'inf') && (!$this->start->compatibleWith($value))) continue;
if (($this->end !== 'inf') && (!$this->end->compatibleWith($value))) continue;
$compatibleCount++;
 
if ($this->warnInsideRange) {
return (($this->start === 'inf') || (VNagValueUomPair::compare($value,$this->start) >= 0)) &&
(($this->end === 'inf') || (VNagValueUomPair::compare($value,$this->end) <= 0));
} else {
return (($this->start !== 'inf') && (VNagValueUomPair::compare($value,$this->start) < 0)) ||
(($this->end !== 'inf') && (VNagValueUomPair::compare($value,$this->end) > 0));
}
}
 
if ((count($values) > 0) and ($compatibleCount == 0)) {
throw new VNagNoCompatibleRangeUomFoundException(VNagLang::$no_compatible_range_uom_found);
}
 
return false;
}
}
 
class VNagValueUomPair {
protected $value;
protected $uom;
public $roundTo = -1;
 
public function isRelative() {
return $this->uom === '%';
}
 
public function getValue() {
return $this->value;
}
 
public function getUom() {
return $this->uom;
}
 
public function __toString() {
if ($this->roundTo == -1) {
return $this->value.$this->uom;
} else {
return round($this->value,$this->roundTo).$this->uom;
}
}
 
public function __construct($str) {
if (!preg_match('/^([\d\.]+)(.*)$/ism', $str, $m)) {
throw new VNagValueUomPairSyntaxException($str);
}
$this->value = $m[1];
$this->uom = isset($m[2]) ? $m[2] : '';
 
if (!self::isKnownUOM($this->uom)) {
throw new VNagUnknownUomException($this->uom);
}
}
 
public static function isKnownUOM($uom) {
// see https://nagios-plugins.org/doc/guidelines.html#AEN200
// 10. UOM (unit of measurement) is one of:
return (
// no unit specified - assume a number (int or float) of things (eg, users, processes, load averages)
($uom === '') ||
// s - seconds (also us, ms)
($uom === 's') || ($uom === 'ms') || ($uom === 'us') ||
// % - percentage
($uom === '%') ||
// B - bytes (also KB, MB, TB)
($uom === 'B') || ($uom === 'KB') || ($uom === 'MB') || ($uom === 'GB') || ($uom === 'TB') || // NOTE: GB is not in the official development guidelines,probably due to an error, so I've added them anyway
// c - a continous counter (such as bytes transmitted on an interface)
($uom === 'c')
);
}
 
public function normalize($target=null) {
$res = clone $this;
 
// The value is normalized to seconds or megabytes
if ($res->uom === 'ms') {
$res->uom = 's';
$res->value /= 1000;
}
if ($res->uom === 'us') {
$res->uom = 's';
$res->value /= 1000 * 1000;
}
if ($res->uom === 'B') {
$res->uom = 'MB';
$res->value /= 1024 * 1024;
}
if ($res->uom === 'KB') {
$res->uom = 'MB';
$res->value /= 1024;
}
if ($res->uom === 'GB') {
$res->uom = 'MB';
$res->value *= 1024;
}
if ($res->uom === 'TB') {
$res->uom = 'MB';
$res->value *= 1024 * 1024;
}
if ($res->uom === 'c') {
$res->uom = '';
}
 
// Now, if the user wishes, convert to another unit
if (!is_null($target)) {
if ($res->uom == 'MB') {
if ($target == 'B') {
$res->uom = 'B';
$res->value *= 1024 * 1024;
} else if ($target == 'KB') {
$res->uom = 'KB';
$res->value *= 1024;
} else if ($target == 'GB') {
$res->uom = 'GB';
$res->value /= 1024;
} else if ($target == 'TB') {
$res->uom = 'TB';
$res->value /= 1024 * 1024;
} else {
throw new VNagUomConvertException($res->uom, $target);
}
} else if ($res->uom == 's') {
if ($target == 'ms') {
$res->uom = 'ms';
$res->value /= 1000;
} else if ($target == 'us') {
$res->uom = 'us';
$res->value /= 1000 * 1000;
} else {
throw new VNagUomConvertException($res->uom, $target);
}
} else {
throw new VNagUomConvertException($res->uom, $target);
}
}
 
return $res;
}
 
public function compatibleWith(VNagValueUomPair $other) {
$a = $this->normalize();
$b = $other->normalize();
 
return ($a->uom == $b->uom);
}
 
public static function compare(VNagValueUomPair $left, VNagValueUomPair $right) {
$a = $left->normalize();
$b = $right->normalize();
 
// FUT: Also accept mixed UOMs, e.g. MB and %
// To translate between an absolute and a relative value, the
// reference value (100%=?) needs to be passed through this comparison
// function somehow.
if ($a->uom != $b->uom) throw new VNagMixedUomsNotImplemented($a->uom, $b->uom);
 
if ($a->value > $b->value) return 1;
if ($a->value == $b->value) return 0;
if ($a->value < $b->value) return -1;
}
}
 
class VNagPerformanceData {
// see https://nagios-plugins.org/doc/guidelines.html#AEN200
// https://www.icinga.com/docs/icinga1/latest/en/perfdata.html#formatperfdata
 
protected $label;
protected /*VNagValueUomPair*/ $value;
protected $warn = null;
protected $crit = null;
protected $min = null;
protected $max = null;
 
public static function createByString($perfdata) {
$perfdata = trim($perfdata);
 
$ary = explode('=',$perfdata);
if (count($ary) != 2) {
throw new VNagInvalidPerformanceDataException(sprintf(VNagLang::$perfdata_line_invalid, $perfdata));
}
$label = $ary[0];
$bry = explode(';',$ary[1]);
if (substr($label,0,1) === "'") $label = substr($label, 1, strlen($label)-2);
$value = $bry[0];
$warn = isset($bry[1]) ? $bry[1] : null;
$crit = isset($bry[2]) ? $bry[2] : null;
$min = isset($bry[3]) ? $bry[3] : null;
$max = isset($bry[4]) ? $bry[4] : null;
 
// Guideline "7. min and max are not required if UOM=%" makes no sense, because
// actually, all fields (except label and value) are optional.
 
return new self($label, $value, $warn, $crit, $min, $max);
}
 
public function __construct($label, $value/*may include UOM*/, $warn=null, $crit=null, $min=null, $max=null) {
// Not checked / Nothing to check:
// - 4. label length is arbitrary, but ideally the first 19 characters are unique (due to a limitation in RRD). Be aware of a limitation in the amount of data that NRPE returns to Nagios
// - 6. warn, crit, min or max may be null (for example, if the threshold is not defined or min and max do not apply). Trailing unfilled semicolons can be dropped
// - 9. warn and crit are in the range format (see the Section called Threshold and ranges). Must be the same UOM
// - 7. min and max are not required if UOM=%
 
// 2. label can contain any characters except the equals sign or single quote (')
if (strpos($label, '=') !== false) throw new VNagInvalidPerformanceDataException(VNagLang::$perfdata_label_equal_sign_forbidden);
 
// 5. to specify a quote character, use two single quotes
$label = str_replace("'", "''", $label);
 
// 8. value, min and max in class [-0-9.]. Must all be the same UOM.
// value may be a literal "U" instead, this would indicate that the actual value couldn't be determined
/*
if (($value != 'U') && (!preg_match('|^[-0-9\\.]+$|', $value, $m))) {
throw new VNagInvalidPerformanceDataException(VNagLang::$perfdata_value_must_be_in_class);
}
*/
if ((!_empty($min)) && (!preg_match('|^[-0-9\\.]+$|', $min, $m))) {
throw new VNagInvalidPerformanceDataException(VNagLang::$perfdata_min_must_be_in_class);
}
if ((!_empty($max)) && (!preg_match('|^[-0-9\\.]+$|', $max, $m))) {
throw new VNagInvalidPerformanceDataException(VNagLang::$perfdata_max_must_be_in_class);
}
 
// 10. UOM (unit of measurement) is one of ....
// => This rule is checked in the VNagValueUomPair constructor.
 
$this->label = $label;
$this->value = ($value == 'U') ? 'U' : new VNagValueUomPair($value);
$this->warn = $warn;
$this->crit = $crit;
$this->min = $min;
$this->max = $max;
}
 
public function __toString() {
$label = $this->label;
$value = $this->value;
$warn = $this->warn;
$crit = $this->crit;
$min = $this->min;
$max = $this->max;
 
// 5. to specify a quote character, use two single quotes
$label = str_replace("''", "'", $label);
 
// 'label'=value[UOM];[warn];[crit];[min];[max]
// 3. the single quotes for the label are optional. Required if spaces are in the label
return "'$label'=$value".
';'.(is_null($warn) ? '' : $warn).
';'.(is_null($crit) ? '' : $crit).
';'.(is_null($min) ? '' : $min).
';'.(is_null($max) ? '' : $max);
}
}
 
class VNagHelp {
public $word_wrap_width = 80; // -1 = disable
public $argument_indent = 7;
 
public function printUsagePage() {
$usage = $this->getUsage();
 
if (_empty($usage)) {
$usage = VNagLang::$no_syntax_defined;
}
 
return trim($usage)."\n";
}
 
public function printVersionPage() {
$out = trim($this->getNameAndVersion())."\n";
 
if ($this->word_wrap_width > 0) $out = wordwrap($out, $this->word_wrap_width, "\n", false);
 
return $out;
}
 
static private function _conditionalLine($line, $terminator='', $prefix='') {
if (!_empty($line)) {
return trim($line).$terminator;
}
return '';
}
 
public function printHelpPage() {
$out = '';
$out .= self::_conditionalLine($this->getNameAndVersion(), "\n");
$out .= self::_conditionalLine($this->getCopyright(), "\n");
$out .= ($out != '') ? "\n" : '';
$out .= self::_conditionalLine($this->getShortDescription(), "\n\n\n");
$out .= self::_conditionalLine($this->getUsage(), "\n\n");
 
$out .= VNagLang::$options."\n";
foreach ($this->options as $argObj) {
$out .= $this->printArgumentHelp($argObj);
}
 
$out .= self::_conditionalLine($this->getFootNotes(), "\n\n", "\n");
 
if ($this->word_wrap_width > 0) $out = wordwrap($out, $this->word_wrap_width, "\n", false);
 
return $out;
}
 
protected /* VNagArgument[] */ $options = array();
 
// Will be called by VNag via ReflectionMethod (like C++ style friends), because it should not be called manually.
// Use VNag's function instead (since it adds to the argHandler too)
protected function _addOption($argObj) {
$this->options[] = $argObj;
}
 
# FUT: Automatic creation of usage page. Which arguments are necessary?
protected function printArgumentHelp($argObj) {
$identifiers = array();
 
$shortopt = $argObj->getShortopt();
if (!_empty($shortopt)) $identifiers[] = '-'.$shortopt;
 
$longopts = $argObj->getLongopts();
if (!is_null($longopts)) {
foreach ($longopts as $longopt) {
if (!_empty($longopt)) $identifiers[] = '--'.$longopt;
}
}
 
if (count($identifiers) == 0) return;
 
$valueName = $argObj->getValueName();
 
$arginfo = '';
switch ($argObj->getValuePolicy()) {
case VNagArgument::VALUE_FORBIDDEN:
$arginfo = '';
break;
case VNagArgument::VALUE_REQUIRED:
$arginfo = '='.$valueName;
break;
case VNagArgument::VALUE_OPTIONAL:
$arginfo = '[='.$valueName.']';
break;
}
 
$out = '';
$out .= implode(', ', $identifiers).$arginfo."\n";
 
// https://nagios-plugins.org/doc/guidelines.html#AEN302 recommends supporting a 80x23 screen resolution.
// While we cannot guarantee the vertical height, we can limit the width at least...
 
$content = trim($argObj->getHelpText());
if ($this->word_wrap_width > 0) $content = wordwrap($content, $this->word_wrap_width-$this->argument_indent, "\n", false);
$lines = explode("\n", $content);
 
foreach ($lines as $line) {
$out .= str_repeat(' ', $this->argument_indent).$line."\n";
}
$out .= "\n";
 
return $out;
}
 
// $pluginName should contain the name of the plugin, without version.
protected $pluginName;
public function setPluginName($pluginName) {
$this->pluginName = $this->replaceStuff($pluginName);
}
public function getPluginName() {
if (_empty($this->pluginName)) {
global $argv;
return basename($argv[0]);
} else {
return $this->pluginName;
}
}
 
private static function isCertified($file) {
$cont = file_get_contents($file);
 
$regex = '@<\?php /\* <ViaThinkSoftSignature>(.+)</ViaThinkSoftSignature> \*/ \?>\n@ismU';
 
if (!preg_match($regex, $cont, $m)) {
return false;
}
$signature = base64_decode($m[1]);
 
$naked = preg_replace($regex, '', $cont);
$hash = hash("sha256", $naked.basename($file));
 
$public_key = <<<'VTSKEY'
-----BEGIN PUBLIC KEY-----
MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEA4UEmad2KHWzfGLcAzbOD
IhqWyoPA1Cg4zN5YK/CWUiE7sh2CNinIwYqGnIOhZLp54/Iyv3H05QeWJU7kD+jQ
5JwR8+pqk8ZGBfqlxXUBJ2bZhYIBJZYfilSROa7jgPPrrw0CjdGLmM3wmc8ztQRv
4GpP7MaKVyVOsRz5xEcpzghWZ+Cl8Nxq1Vo02RkMYOOPA16abxZ65lVM8Vv2EKGf
/VAVViTFvLWPxggvt1fbJJniC0cwt8gjzFXt6IJJSRlqc1lOO9ZIa/EWDKuHKQ1n
ENQCqnuVPFDZU3lU20Z+6+EA0YngcvNYi3ucdIvgBd4Yv5FetzuxiOZUoDRfh/3R
6dCJ8CvRiq0BSZcynTIWNmF3AVsH7vjxZe8kMDbwZNnR0suZ5MfBh6L/s1lCEWlS
GwmCLc3MnOLxq3JLnfmbVa509YxlUamdSswnvzes28AjnzQ3LQchspP2a8bSXH6/
qpbwvmV5WiNgwJck04VhaXrRRy3XFSwuk7KU/L4aqadXP26kgDqIYNvPXSa9JyGc
14zwdmAtn36o8vpXM/A7GhdWqgPLlJbdTdK6IfwpBs8P/JB6y3t6RzAGiEOITdj9
QUhW+sAoKno0j4WT7s80vWNWz37WoFJcvVLnVEYitnW6DqM+GOt2od3g6WgI6dOa
MESA4J44Y4x1gXBw/M6F/ZngP4EJoAUG0GbzsaZ6HKLt4pDTZmw8PnNcXrOMYkr/
N5EliTXil45DCaLkgNJmpdXjNpIvShW4ogq2osw+SQUalnAbW8ddiaOVCdgXkDFq
gvnl5QSeUrKPF5v+vlnwWar6Rp7iInQpnA+PTSbAlO3Dd9WqbWx+uNoI/kXUlN0O
a/vi5Uwat2Bz3N+jIpnBqg4+O+SG0z3UCVmT6Leg+kqO/rXbzoVv/DV7E30vTqdo
wsswdJEM1BI7Wyid6HPwBek+rdv77gUg3W37vUcdfKxsYRcoHriXLHpmENznJcEx
/nvilw6To1zx2LKmM/p56MQriKkXnqoOBpkpn3PaWyXZKY9xJNTAbcSP3haE7z9p
PzJw88KI8dnYuFg4yS/AgmVGAUtu3bhDG4qF9URu2ck868zViH996lraYkmFIWJG
r7h1LImhrwDEJvb/rOW8QvOZBX9H6pcSKs/LQbeoy6HMIOTlny+S15xtiS4t6Ayv
3m0ry5c0qkl/mgKvGpeRnNlrcr6mb2fzxxGvcuBzi25wgIbRLPgJoqsmeBvW1OLU
+9DpkNvitEJnPRo86v0VF86aou12Sm8Wb4mtrQ7h3qLIYvw2LN2mYh4WlgrSwPpx
YvE2+vWapilnnDWoiu2ZmDWa7WW/ihqvX9fmp/qzxQvJmBYIN8dFpgcNLqSx526N
bwIDAQAB
-----END PUBLIC KEY-----
VTSKEY;
 
if (!openssl_verify($hash, $signature, $public_key, OPENSSL_ALGO_SHA256)) {
return false;
}
 
return true;
}
 
// $version should contain the version, not the program name or copyright.
protected $version;
public function setVersion($version) {
$this->version = $this->replaceStuff($version);
}
public function getVersion() {
return $this->version;
}
public function getNameAndVersion() {
$ret = $this->getPluginName();
if (_empty($ret)) return null;
 
$ver = $this->getVersion();
if (!_empty($ver)) {
$ret = sprintf(VNagLang::$x_version_x, $ret, $ver);
}
$ret = trim($ret);
 
$certified = true;
foreach (get_included_files() as $file) {
$certified &= self::isCertified($file);
}
if ($certified) {
$ret .= ' (' . VNagLang::$certified . ')';
}
 
return $ret;
}
 
// $copyright should contain the copyright only, no program name or version.
// $CURYEAR$ will be replaced by the current year
protected $copyright;
public function setCopyright($copyright) {
$this->copyright = $this->replaceStuff($copyright);
}
 
private function getVNagCopyright() {
if (VNag::is_http_mode()) {
$vts_email = 'www.viathinksoft.com'; // don't publish email address at web services because of spam bots
} else {
$vts_email = base64_decode('aW5mb0B2aWF0aGlua3NvZnQuZGU='); // protect email address from spambots which might parse this code
}
return "VNag Framework ".VNag::VNAG_VERSION." (C) 2014-".date('Y')." ViaThinkSoft <$vts_email>";
}
 
public function getCopyright() {
if (_empty($this->copyright)) {
return sprintf(VNagLang::$plugin_uses, $this->getVNagCopyright());
} else {
return trim($this->copyright)."\n".sprintf(VNagLang::$uses, $this->getVNagCopyright());
}
}
 
// $shortDescription should describe what this plugin does.
protected $shortDescription;
public function setShortDescription($shortDescription) {
$this->shortDescription = $this->replaceStuff($shortDescription);
}
public function getShortDescription() {
if (_empty($this->shortDescription)) {
return null;
} else {
$content = $this->shortDescription;
if ($this->word_wrap_width > 0) $content = wordwrap($content, $this->word_wrap_width, "\n", false);
return $content;
}
}
 
protected function replaceStuff($text) {
global $argv;
$text = str_replace('$SCRIPTNAME$', $argv[0], $text);
$text = str_replace('$CURYEAR$', date('Y'), $text);
return $text;
}
 
// $syntax should contain the option syntax only, no explanations.
// $SCRIPTNAME$ will be replaced by the actual script name
// $CURYEAR$ will be replaced by the current year
# FUT: Automatically generate syntax?
protected $syntax;
public function setSyntax($syntax) {
$syntax = $this->replaceStuff($syntax);
$this->syntax = $syntax;
}
public function getUsage() {
if (_empty($this->syntax)) {
return null;
} else {
return sprintf(VNagLang::$usage_x, $this->syntax);
}
}
 
// $footNotes can be contact information or other notes which should appear in --help
protected $footNotes;
public function setFootNotes($footNotes) {
$this->footNotes = $this->replaceStuff($footNotes);
}
public function getFootNotes() {
return $this->footNotes;
}
}
 
class VNagLang {
public static function status($code, $statusmodel) {
switch ($statusmodel) {
case VNag::STATUSMODEL_SERVICE:
switch ($code) {
case VNag::STATUS_OK:
return 'OK';
break;
case VNag::STATUS_WARNING:
return 'Warning';
break;
case VNag::STATUS_CRITICAL:
return 'Critical';
break;
case VNag::STATUS_UNKNOWN:
return 'Unknown';
break;
default:
return sprintf('Error (%d)', $code);
break;
}
break;
case VNag::STATUSMODEL_HOST:
switch ($code) {
case VNag::STATUS_UP:
return 'Up';
break;
case VNag::STATUS_DOWN:
return 'Down';
break;
default:
return sprintf('Maintain last state (%d)', $code);
break;
}
break;
default:
throw new VNagIllegalStatusModel(sprintf(self::$illegal_statusmodel, $statusmodel));
break;
}
}
 
static $nagios_output = 'VNag-Output';
static $verbose_info = 'Verbose information';
static $status = 'Status';
static $message = 'Message';
static $performance_data = 'Performance data';
static $status_ok = 'OK';
static $status_warn = 'Warning';
static $status_critical = 'Critical';
static $status_unknown = 'Unknown';
static $status_error = 'Error';
static $unhandled_exception_without_msg = "Unhandled exception of type %s";
static $plugin_uses = 'This plugin uses %s';
static $uses = 'uses %s';
static $x_version_x = '%s, version %s';
 
// Argument names (help page)
static $argname_value = 'value';
static $argname_seconds = 'seconds';
static $certified = 'Certified by ViaThinkSoft';
 
// Exceptions
static $query_without_expected_argument = "The argument '%s' is queried, but was not added to the list of expected arguments. Please contact the plugin author.";
static $required_argument_missing = "The argument '%s' is required.";
static $performance_data_invalid = 'Performance data invalid.';
static $no_standard_arguments_with_letter = "No standard argument with letter '%s' exists.";
static $invalid_start_value = 'Invalid start value.';
static $invalid_end_value = 'Invalid end value.';
static $start_is_greater_than_end = 'Start is greater than end value.';
static $value_name_forbidden = "Implementation error: You may not define a value name for the argument, because the value policy is VALUE_FORBIDDEN.";
static $value_name_required = "Implementation error: Please define a name for the argument (so it can be shown in the help page).";
static $illegal_shortopt = "Illegal shortopt '-%s'.";
static $illegal_longopt = "Illegal longopt '--%s'.";
static $illegal_valuepolicy = "valuePolicy has illegal value '%s'.";
static $range_invalid_syntax = "Syntax error in range '%s'.";
static $timeout_value_invalid = "Timeout value '%s' is invalid.";
static $range_is_invalid = 'Range is invalid.';
static $timeout_exception = 'Timeout!';
static $perfdata_label_equal_sign_forbidden = 'Label may not contain an equal sign.';
static $perfdata_value_must_be_in_class = 'Value must be in class [-0-9.] or be \'U\' if the actual value can\'t be determined.';
static $perfdata_min_must_be_in_class = 'Min must be in class [-0-9.] or empty.';
static $perfdata_max_must_be_in_class = 'Max must be in class [-0-9.] or empty.';
static $perfdata_uom_not_recognized = 'UOM (unit of measurement) "%s" is not recognized.';
static $perfdata_mixed_uom_not_implemented = 'Mixed UOMs (%s and %s) are currently not supported.';
static $no_compatible_range_uom_found = 'Measured values are not compatible with the provided warning/critical parameter. Most likely, the UOM is incompatible.';
static $exception_x = '%s (%s)';
static $no_syntax_defined = 'The author of this plugin has not defined a syntax for this plugin.';
static $usage_x = "Usage:\n%s";
static $options = "Options:";
static $illegal_statusmodel = "Invalid statusmodel %d.";
static $none = '[none]';
static $valueUomPairSyntaxError = 'Syntax error at "%s". Syntax must be Value[UOM].';
static $too_few_warning_ranges = "You have too few warning ranges (currently trying to get element %d).";
static $too_few_critical_ranges = "You have too few critical ranges (currently trying to get element %d).";
static $dataset_missing = 'Dataset missing.';
static $payload_not_base64 = 'The payload is not valid Base64.';
static $payload_not_json = 'The payload is not valid JSON.';
static $signature_missing = 'The signature is missing.';
static $signature_not_bas64 = 'The signature is not valid Base64.';
static $signature_invalid = 'The signature is invalid. The connection might have been tampered, or a different key is used.';
static $pubkey_file_not_found = "Public key file %s was not found.";
static $pubkey_file_not_readable = "Public key file %s is not readable.";
static $privkey_file_not_found = "Private key file %s was not found.";
static $privkey_file_not_readable = "Private key file %s is not readable.";
static $perfdata_line_invalid = "Performance data line %s is invalid.";
static $singlevalue_unexpected_at_symbol = 'This plugin does not allow the @-symbol at ranges for single values.';
static $illegalSingleValueBehavior = "Illegal value for 'singleValueBehavior'. Please contact the creator of the plugin.";
static $dataset_encryption_no_array = 'Dataset encryption information invalid.';
static $require_password = 'This resource is protected with a password. Please provide a password.';
static $wrong_password = 'This resource is protected with a password. You have provided the wrong password, or it was changed.';
static $convert_x_y_error = 'Cannot convert from UOM %s to UOM %s.';
static $php_error = 'PHP has detected an error in the plugin. Please contact the plugin author.';
static $output_level_lowered = "Output Buffer level lowered during cbRun(). Please contact the plugin author.";
 
// Help texts
static $warning_range = 'Warning range';
static $critical_range = 'Critical range';
static $prints_version = 'Prints version';
static $verbosity_helptext = 'Verbosity -v, -vv or -vvv';
static $timeout_helptext = 'Sets timeout in seconds';
static $help_helptext = 'Prints help page';
static $prints_usage = 'Prints usage';
 
static $notConstructed = 'Parent constructor not called with parent::__construct().';
}
 
function vnagErrorHandler($errorkind, $errortext, $file, $line) {
if (!(error_reporting() & $errorkind)) {
// Code is not included in error_reporting. Don't do anything.
return;
}
 
while (ob_get_level() > 0) @ob_end_clean();
 
// We want 100% clean scripts, so any error, warning or notice will shutdown the script
// This also fixes the issue that PHP will end with result code 0, showing an error.
 
// Error kinds see http://php.net/manual/en/errorfunc.constants.php
if (defined('E_ERROR') && ($errorkind == E_ERROR)) $errorkind = 'Error';
if (defined('E_WARNING') && ($errorkind == E_WARNING)) $errorkind = 'Warning';
if (defined('E_PARSE') && ($errorkind == E_PARSE)) $errorkind = 'Parse';
if (defined('E_NOTICE') && ($errorkind == E_NOTICE)) $errorkind = 'Notice';
if (defined('E_CORE_ERROR') && ($errorkind == E_CORE_ERROR)) $errorkind = 'Core Error';
if (defined('E_CORE_WARNING') && ($errorkind == E_CORE_WARNING)) $errorkind = 'Core Warning';
if (defined('E_COMPILE_ERROR') && ($errorkind == E_COMPILE_ERROR)) $errorkind = 'Compile Error';
if (defined('E_COMPILE_WARNING') && ($errorkind == E_COMPILE_WARNING)) $errorkind = 'Compile Warning';
if (defined('E_USER_ERROR') && ($errorkind == E_USER_ERROR)) $errorkind = 'User Error';
if (defined('E_USER_WARNING') && ($errorkind == E_USER_WARNING)) $errorkind = 'User Warning';
if (defined('E_USER_NOTICE') && ($errorkind == E_USER_NOTICE)) $errorkind = 'User Notice';
if (defined('E_STRICT') && ($errorkind == E_STRICT)) $errorkind = 'Strict';
if (defined('E_RECOVERABLE_ERROR') && ($errorkind == E_RECOVERABLE_ERROR)) $errorkind = 'Recoverable Error';
if (defined('E_DEPRECATED') && ($errorkind == E_DEPRECATED)) $errorkind = 'Deprecated';
if (defined('E_USER_DEPRECATED') && ($errorkind == E_USER_DEPRECATED)) $errorkind = 'User Deprecated';
throw new VNagException(VNagLang::$php_error . " $errortext at $file:$line (kind $errorkind)");
 
// true = the PHP internal error handling will not be called.
return true;
}
 
$old_error_handler = set_error_handler("vnagErrorHandler");
 
// === End of document ===
/trunk/logos/vnag_logo.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/logos/vnag_logo.psd
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/logos/vnag_logo_400.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/plugins/4images_version/FourImagesVersionCheck.class.php
0,0 → 1,83
<?php /* <ViaThinkSoftSignature>muCA1BNAx3t4UMIIzqCeb9w0THNUjzz6c/qmRy6zLtsiwU3WE0nJFpHwi6R1B3jhrivN4x+RGN9wo2YCpenFDreN0+k4oHsxsqz68eiaiH2+1Z5bKXMayUNG97mFdbWxIxAt1VWBRG4GSXnAbkX3ubNhQw1e2WptqpT4SufS5KcGaaI/MxwRrBdjheyENnNahSFnjM4LHw6R2On+P5RCML9aReiYLECYhZPi/WlqOI7aj46Qfu5g29s6qxfKEc3HWGoXkJi706o9G4j/nffo16EBrgpjLMQxO7z7nhsbbaucABnMuDu50ViFmJRMi6j0ys5SYwrLuoa3VqGL73Gxy7agJgF/4+35Q4LArCyhIIg7xmtOmC+vKIDlJD9cmUpIBT3th9Sxqzl5uMkoqZRpBzOtTIKFX/p4I6VbJSjroHVcCO5rUbwzXZDshdLdbULXTOR8/dJs3aqOPpPbMasblpVc6oRfePS1Wy1agYBl5kbZErJeYr2ZerhsAdwvkoXjM14Sk6Ol9evRdSbdGDVK3x1zJSvoW4yE+tImN7zCnlqCc4AD2u8EWjDXCGfhkaAzbbqf8Geo6TSJQm3YUJWfZFP0y7SYfyzeYt7ZVHyLcUNxowRsAfYndXn2700HqJP1pDtmWEVcnJpbie9BwDkasWbgCXypXcRAItnHDndYIyxxCTYfXamZIrhmQ40aJow1WYEpDzj1TI9vmFTXh0ciY9/rvMATofiUOCgyn6k2BukNFND3oFr9M/FsPx6UFnmjprphQdQSvcIu+VnrnQRRRCwvJRHqjvbZVjN8/aluTPWib5+ITMW0PdrfzXPgZbzLjpBFLg1nHtC7dxFQ/8OyCibCe0+SY0nLyq/TFBbSBjaK96kXjOT8xp5aVyGiSrXm8wPh1WtlOaJhrj5cNP0si/rd7vmLzyxC/eplqddVyfbKVNZRyjbcyyg1D5Wsg9uhp+sgnMSPad1O6yw44rfbtnyT+imUWXoqU4h3B+h21BYIFnYqvJtA/UfloimomfvNxjqiwX0oHuYII3Dv/b14JGXGaps/PaxRvQjxEHOvVZhU5Eus9piYihgQxhq6/B5A6d1Om7iZsyIkOvX+F45WuazvoEc3gs3c6F8EmGY1i4vdSJ6ws9VueJSyyE0hPePGV7vJQ92EduP/j2Yna6cOcNP0W26gNlTcQO2G0K4zm5ZBI5RhocRsTKHxm9XQIA2+KgjvpEupb5R+Sqt7NKPDfMtFiTSoPkCaB1Qgc5JDdJqXlpOm4dlT9OCryAqMvcBJSDchNM+/u7gbk/P5zBZHGpn0BcCkX409jH7Z1l5rMKTwOkInPxD1XkUnXO55HMR2/m+TDlk3BnA6fgIau2eajQ==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
class FourImagesVersionCheck extends VNag {
protected $argSystemDir = null;
 
public function __construct() {
parent::__construct();
 
$this->registerExpectedStandardArguments('Vht');
 
$this->getHelpManager()->setPluginName('check_4images_version');
$this->getHelpManager()->setVersion('1.0');
$this->getHelpManager()->setShortDescription('This plugin checks if a local 4images system has the latest version installed.');
$this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
$this->getHelpManager()->setSyntax('$SCRIPTNAME$ [-d <directory>]');
$this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
 
// Individual (non-standard) arguments:
$this->addExpectedArgument($this->argSystemDir = new VNagArgument('d', 'directory', VNagArgument::VALUE_REQUIRED, '4imagesPath', 'The local directory where your 4images installation is located.'));
}
 
protected function get_4images_version($path) {
$path = realpath($path) === false ? $path : realpath($path);
 
$cont = @file_get_contents("$path/includes/constants.php");
if (!preg_match("@define\('SCRIPT_VERSION', '(.*)'\);@ismU", $cont, $m)) {
throw new Exception("Cannot find version information at $path");
}
 
return $m[1];
}
 
protected function get_latest_version() {
$cont = @file_get_contents('https://www.4homepages.de/download-4images');
if (!$cont) {
throw new Exception("Cannot access website with latest version");
}
 
if (!preg_match('@<h2>Download 4images (.+)</h2>@ismU', $cont, $m)) {
if (!preg_match('@>Current Version: (.+)</a>@ismU', $cont, $m)) {
throw new Exception("Cannot find version information on the website");
}
}
 
return trim($m[1]);
}
 
protected function cbRun($optional_args=array()) {
$system_dir = $this->argSystemDir->getValue();
if (empty($system_dir)) {
throw new Exception("Please specify the directory of the 4images installation.");
}
$system_dir = realpath($system_dir) === false ? $system_dir : realpath($system_dir);
 
if (!is_dir($system_dir)) {
throw new Exception('Directory "'.$system_dir.'" not found.', false);
}
 
$version = $this->get_4images_version($system_dir);
 
$latest_version = $this->get_latest_version();
 
if ($version == $latest_version) {
$this->setStatus(VNag::STATUS_OK);
$this->setHeadline("Version $version at $system_dir", true);
} else {
$this->setStatus(VNag::STATUS_WARNING);
$this->setHeadline("Version $version is outdated (Latest version is $latest_version) at $system_dir", true);
}
}
}
 
/trunk/plugins/4images_version/check_4images_version
0,0 → 1,20
#!/usr/bin/php
<?php /* <ViaThinkSoftSignature>mqBnKaXSvntQ2sKRBSFLC8Jre/OPbS6gG7zOOohQ7UABuNjjx6B0QAmobWx/gr5mD66TNU1l6dl/GqFkVssrXZmX/W2FE39l16535SCG2PtitBHjcU9S9WNqlaYAvegNikmlB4cpjL183hJHDvhQtijiEaO+vZJqqI5h+KHopeVZi9eT5vqFZ+kfIxlGWhXNMjSoSswAiVLPOSfMQADA9uGA6dcSpvPOpR/T6ga9EavD+9sCNaF+ToCLgTEMnMUmEn5Xhk/z1TjVXuLs52juiRjZT3XN21f1oKJOxa0bLWWzSIyyg2+VjgC4zaGqcbJzDDxQkghnftU91HePNtkcwxZJuFTNwWDbg77+hObkLz8gQ/gPBuGcRlbdrIyuHcHdMLlRTBoa8h9mmu8u71E9RVAZteZAT6ct0Io9nQJv/wVEfZmFw/WBN/YGHy7HYEqgtuHWHeUvpSjT0eOxoDZmYpZXF1uhvPnLXBqhrtJJ7kDxL3kZ6Tgd4i8d7hSaN7Pbq0JLE30Hri5Onw5cfh7Q+k5/oPxWsTLsrIQiAXKP6THaenFkeLK0pn1RtzMCpJZIvMjHW4FhVLZrhGB8rrQu3gbdi5gYLrwx3XOA547guDeHF9FTB5yj9kE2CR9P0ubQjGpMBxiyfB9AZN5q9aXSp+NkauHfqUiArEbApwMAnGuhjjeeWQ5+IcfYKhZqev9+O8lbhA0Oz6kLbCGJQ8iLaK5nN85t/x4buW2n1emS6blWYGWXMEWRZrue8KhNnpK5bdd0Dyke2jHO0/4RcYKrdplh++87/Y8JI+bBy6mFHKYMJgkxd/b2bNSQ4+WLUyExKs3aLAzU/Gu0MgCczHYpEuHqENqpKZpBbo5MXw8Iqi/B6OdoH69lBBXeeKGTv3JnhieX5coDyPIW/+BUUfS4NsQ07LhXr2bAAmGh8JXjRiGS98khzqx86icEF4tb7cViwzJ8bbTnLPxJqukekV5hjDEcO9CJ29C6Gimkl2FNigj2mayjZeRZbjk5owWC7OPzdcaRV/bFKpXzU63/eJHcfQVHQH+OhrvWCwSjFxwSxzcWKZMsI9UwDELTW/LfcI+XDtQEtuDBI1K3c3pD5weuWWs4RmAx+Xw4Kga0XVW4FYXjShNMl5slvGJZUF1WF7iJs18ZTL6jqDOyuzYO0DZHdPKqPSZRRT70gJgWIEigxrYZKIADYNlvirzn+0gu2+g7k50X3153wJ3W89Cs0v8LY8l5qHo9a+WnvbNkl7zOgA9WBEAeM0LMTuOF4Q6f+3s1iTnlXB5RgjfbIG2DDHDrMOtvwNWaV65YiZriO4VAmBjMqlWDW9cMUIGU2jiMU3RiZQmgiL7CRt6eBwWRiJLxDQ==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__ . '/FourImagesVersionCheck.class.php';
 
$job = new FourImagesVersionCheck();
$job->run();
unset($job);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/4images_version/icinga2.conf
0,0 → 1,48
// Put this file in /etc/icinga2/conf.d/...
 
// VNag - Nagios Framework for PHP
// Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
// Licensed under the terms of the Apache 2.0 license
//
// Revision 2018-07-15
 
object CheckCommand "vnag_4images_version" {
command = [ "/daten/vnag/plugins/4images_version/check_4images_version" ]
 
arguments = {
"-d" = {
value = "$vnag_4images_version_dir$"
description = "Location where the 4images installation is located"
required = true
}
}
}
 
// Example usage:
//
// apply Service "example_website1_4images_version" {
// import "generic-service"
// check_command = "vnag_4images_version"
// vars = {
// vnag_4images_version_dir = "/var/www/website1/4images/"
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_website2_4images_version" {
// import "generic-service"
// check_command = "vnag_4images_version"
// vars = {
// vnag_4images_version_dir = "/var/www/website2/4images/"
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_website3_4images_version" {
// import "generic-service"
// check_command = "vnag_4images_version"
// vars = {
// vnag_4images_version_dir = "/var/www/website3/4images/"
// }
// assign where host.name == NodeName
// }
/trunk/plugins/disk_running/DiskRunningCheck.class.php
0,0 → 1,85
<?php /* <ViaThinkSoftSignature>F9z2AfT7nAZ8u/BI8TAx/BdR2s+t778tdYJG4+lJV7Oqve9Zovt7XxsagYPLn4q3acTV8dGL2yaMvIWdPqwpWhu9ssXL9NN81pvIItF5t7GR9NWGS71nHMrr9pjQoIn+R6exKklwpuSMMQgFYKiCh5tUKnaMtEgQm/uQYTRei2UhOeV1s59MJ5/b6TOOcy/NNkO/lYQuflZ+mk5L3VcBtdi6F8sLhoiw4gy+oDDyNpGNSNjiB0mi3CMuQDXpnuAOSv9JluhQMRhQlTfKKaiF+4J7EGKuW3D8lt5FKuF+rGca1Iixtbi4bemQ9RqY3pbgKPg/iNdpxY+j24FcRJ7P6QvHBcY+lb1YL0ss9LqxMOV6DeNg+UOu5Aa1AerA8vfIQ4k7iK8Wt1e+9FXsmGmm84SgJ0gukRNRSzCreb+9glJ52V/PMNZcAiH7Qe7O/bzSeaqHlGIsgghkwt+XEBfyAiemuwBRN5GzyJsMOK7VH1Z+YGcj+V9I3SKkfZVABP6zyq/GwN4EOA2sQ9OCo3PVOcreVsIR+mYTUPfWBB+pd/M9Pu73LnA2WweoeKk/owrrb//uDEfBpCa5TIiDahng2xKaBBZTBJ++mO1kSzBP8X+n5KQToQQCmTzSJvZBXB6h4dqOVm6DikflV62JzOPP2839u48PMIo/6NFheEJnSHLR88f1X0B1lDmAgyc41m1sVk55hiTV5QQ9OJthifgehh9p0kakzY5H1PmltTrwlzBbFFE7BypH1rwyzRCwlXMKlFl74DWAY69ZRs6UaOXC0gbuKJT+blD4dfuEuUut/fQyFYwsFsyPgPzhjAsqnVgHT5IbkBrw2tVZ9NZgraYZjZyW+OFBFMk6fhvuxKzPxJXCHT2JAZ6hTwUPoPfq1GogrDMMmLQ0rorUgVMGuCN/lYtB57ak7QiE6Eczyob8qM60r+m738RysL5Jxg6IPGoT1rtekQKqAFGXUT50jOeTCu6aOSFwLCbisGf+ospZ1POtgFofTPygQJgO2uEkfPDjgkd04oP/p4S9UgIpUDQwlxZkz+MV2ErOSegvpcirTwt7OT2nJNN/FZUE3SOpP6tsRbYH+61kEhmbRK70ebeX6kwF8C6LB+eBvxMgups32MsFQOMucsqmyxV/uz5SM2BLn1giTn13fjJZMhnmz5fqHequgbiJ7vIUjUOpE/ccB6EuRFtirMNlZrVq3J26VEy9s3T9Rd/nV1k+cWLda+lBoLszPI7pRHOIda37RGTbWNPhvxDkG5sIVERQH8/rgTmBK1V/1tabXwDSn6FvzddVKPyXgcXsGefz6TcUMB0c0JMhnRY+/+m/MCQ1mAppVbAQUX+Ha9CJR1xw0e5P+hePww==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-11-04
*/
 
declare(ticks=1);
 
class DiskRunningCheck extends VNag {
// Currently, we do not accept wildcards ('sd*' and 'hd*') because this plugin should monitor if disks become offline, e.g. horribly fail or get disconnected.
// If that would happen, the disk might vanish from the device-folder and therefore would not be detected by the wildcard anymore.
protected $argDisks = null;
 
public function __construct() {
parent::__construct();
 
if ($this->is_http_mode()) {
// Don't allow the standard arguments via $_REQUEST
$this->registerExpectedStandardArguments('');
} else {
$this->registerExpectedStandardArguments('Vhtv');
}
 
$this->getHelpManager()->setPluginName('vnag_disk_running');
$this->getHelpManager()->setVersion('1.0');
$this->getHelpManager()->setShortDescription('This plugin checks if a disk is running/online, even if no SMART functionality is available.');
$this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
$this->getHelpManager()->setSyntax('$SCRIPTNAME$ -d diskname[,diskname[,...]]');
$this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
 
// Individual (non-standard) arguments:
$this->addExpectedArgument($this->argDisks = new VNagArgument('d', 'disknames', VNagArgument::VALUE_REQUIRED, 'disks', 'Disks to be monitored, e.g. "sda,sdb"'));
}
 
protected function cbRun() {
$count_total = 0;
$count_running = 0;
$count_offline = 0;
$count_unknown = 0;
 
$disks = $this->argDisks->getValue();
if (empty($disks)) {
throw new Exception("Please specify the disks you want to monitor.");
}
$disks = explode(',',$disks);
 
foreach ($disks as $disk) {
// We do not check the size, in case the user has more than 26 disks; https://rwmj.wordpress.com/2011/01/09/how-are-linux-drives-named-beyond-drive-26-devsdz/
// But we check if everything is OK, and nothing nasty is done here
$disk = preg_replace('@[^a-zA-Z0-9]@', '', $disk);
 
$count_total++;
if (!file_exists("/dev/$disk")) {
$this->addVerboseMessage("$disk : Drive does not exist", VNag::VERBOSITY_SUMMARY);
$this->setStatus(VNag::STATUS_CRITICAL);
$count_offline++;
} else {
$state_file = "/sys/block/$disk/device/state";
if (!file_exists($state_file)) {
$this->addVerboseMessage("$disk : Cannot fetch state (Is this a valid block device?)", VNag::VERBOSITY_SUMMARY);
$this->setStatus(VNag::STATUS_CRITICAL);
$count_unknown++;
} else {
$state = trim(file_get_contents($state_file));
if ($state != 'running') {
$this->addVerboseMessage("$disk : $state", VNag::VERBOSITY_SUMMARY);
$this->setStatus(VNag::STATUS_CRITICAL);
$count_offline++;
} else {
$this->addVerboseMessage("$disk : $state", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
$this->setStatus(VNag::STATUS_OK); // Note: This won't unset a previously set critical state
$count_running++;
}
}
}
}
 
$this->setHeadline(sprintf('Checked %d disks (%d running, %d offline, %d unknown)', $count_total, $count_running, $count_offline, $count_unknown));
}
}
/trunk/plugins/disk_running/check_disk_running
0,0 → 1,20
#!/usr/bin/php
<?php /* <ViaThinkSoftSignature>Jb7vImFaEfIbD/bEBosJ7WbTWaSLsZAjImdNMNjIFowln2hx8D8wTwOaMCEFr6nuCxZR0KTGn5d2WTVKVdyoZTkLthgsItVd7VfCMF9cq6XegGCMkEs3Akj9m/tPMjG5zWhTaLUCIujT0G7YniAq1nF4F2QgfOcbN8V7yo2WR/DM3Dj1DFVhY8xfwso8BQNV1wa7M/JikdtEC67UqCPwba4Op+5XNeVHJZXLWuMG0oMGKkG8xtSH6jqzFH5Im1YidcRkldmfH2+vyDwt8nIPNE25q66NS6sST7VnqNjDbROyqe8ox5lLZKm2ZQKQ+YTdjSyghvYUbBL2htrnDealjyVio+t942b7LPEyHypHj7NoFkUpPvmZUwjm07+cRLdLsbhR7LxM7n5ch6/IKffexszjKiaAQoBenwrLMfqaYF+rVTQKbeNW2L9kwL/CpMnZDF4sCIm0spvZS6TQcNTz93MkIMgvQw4h2irLsN5E6fw3CMq/B7mxmO2TsVlMeynhNH1PFHVFT3byByBaRM+KpmL9wBM1zMSyaL4M2QhcfCB0y98W+bz98Kc1M8xTlDS3LARP+f6TJz+F9M1nUzLzlToiq9hIN7eMQPjMLy6UoeQ7uIEjlEC3Lxwvv58lP0YcYyy1FQsftvZbfWcpW7C9zzfl8ANyxjv7bV0VejpIF0if4P+I1XxTjSz47bcKLW/SVZRM0Hcc3pE8lm0mkikHvn6JuJ06YWLK93erRRm9JNQeB6IICW+XfhpqoZeUizP0GXipJWqzA2GDiKCDA9PaLR7Code3yYjJgT163MDL6iuOncftSK70I5dk8kQsXRZc+4cKYOaEBfLny6nJNCPeFrPLT/rkASl0gom9fwYl5OQ5wJ0Z4ZXjbTpms8eLuY5Q9zCQ5IFCnPKTxpasoBwm1hpbI8pwYP2mf/v9InhFxWwDEUbR/IuFa9S/q0m7dvCt/gsWGJXnSgg+wNI5400ploUGidZUuhNBlqQ8uRToXCSk8dzvDwm8i99lhV+3k6Mw4JPasnAR1dKAAXlmzE8fHgvuRRYmXR62brWz/Yn4adWIJj3Bnd0StfAPyLmHM9GfLLq5Rn+i/eAOGFJj2iDZOY79Z2TImd18hWGjjz9FcYr1D0alD+ImD2xiB3vdOU2iXyY3URH72w1x1ZDTNCbcbMmZeyMqZUzuF0cYJYSnDGHYiR+myXSXiN4Ia1O7V18/xJpEVwxzsSbiKMagYoFdKM9aK6XDrYQX0Dl3UcbI42i9OZb2IYSJ2Jmurg4x8+TTrU+ou5G8s+/VWn9Cx6E9gmLD7iIT1GVjp9eUg1K3saEHxAJs5zWi/tVBwu4diW6AEpV20XGWuwaLa5eTMx3qGA==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-11-04
*/
 
declare(ticks=1);
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__.'/DiskRunningCheck.class.php';
 
$job = new DiskRunningCheck();
$job->run();
unset($job);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/disk_running/icinga2.conf
0,0 → 1,35
// Put this file in /etc/icinga2/conf.d/...
 
// VNag - Nagios Framework for PHP
// Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
// Licensed under the terms of the Apache 2.0 license
//
// Revision 2018-11-04
 
object CheckCommand "vnag_disk_running" {
command = [ "/daten/vnag/plugins/disk_running/check_disk_running" ]
 
arguments = {
"-d" = {
value = "$vnag_disk_running_disks$"
description = "Disks to be monitored; can be comma separated, e.g. 'sda,sdb'"
required = true
}
"-v" = {
set_if = "$vnag_disk_running_verbose$"
description = "Additionally list drives which are OK, not just the drives which are offline."
}
}
}
 
// Example usage:
//
// apply Service "example_disk_running" {
// import "generic-service"
// check_command = "vnag_disk_running"
// vars = {
// vnag_disk_running_disks = "sda,sdb"
// vnag_disk_running_verbose = false
// }
// assign where host.name == NodeName
// }
/trunk/plugins/file_timestamp/FileTimestampCheck.class.php
0,0 → 1,136
<?php /* <ViaThinkSoftSignature>zGZPz4tVkmDMjrF+v+xuP5dMnqRI4kbdU8ojps0jpGMRwVFzfd6cmeRy1+67gqLA94NEGq7tz9T+gVN8HmmxkW4BiD6dWzrcLrZwtiiVx/C8LS7SB71SKfpVaISx0v2RjHek77YzcQQaC6v1D/p1iPFjNJe1W/XITfCdGQjUxODY84f5iyMRFgeCl4/TK1xqeaCaiBvMbyr/ypo+Zq90TtXDQdYezgF8xQv/yDgP/qYGKTDq7ya3wUjGmCR+DViT6DFQ6doi/kAGWTsa9KflYYcuYY9L/MJnDsSXZqFjc30BBqxsAjZaQZcQnZHYLmlmyEIBtYZn/UOG9Z67E6/tq1OBW8styEyw59z4DFNB+uIqLtx5Ip/JLoNcEfG4jxQVISZ1QCxzYHQ+LaaTk3yDM5hIQ4Cm5z+L6w9YfQ+JGho0CUGDgo0QL+0f4fKW+YETrcEzwYOVqX7Ry6DujKgTWIVKkU1yT/7bg3KdPAJKHaHuBWqqHIMCuTE+muhJd/t6jyOXcuayGKlI3jey33fdrW7CaVpMsUDeFmM7QRMPrvWv+HiY0fu406F6dlQxPSqmMZHTxZ4UH1LkREzFBEyJet7vlazVrLKBmWk83l37lwWrlL5Ehw0RtZGanLLLxNqyDfh6iGjRI9yJDOI+68oMoeF5rnchLJYJ2bMJ2lqJ+0cGy9foFdbCPqd+iPDK/KwmNHXwkZQvuDeKLuJycCKUt2x2CMoIX6GkF4jHAC860AZ2f0A9n6OFXPHfDgZAwWhdKYK8M6ob0QVSTICsBiFAMKkQM8t/BM2FnUPgB1a/m9wPaao/4Xx7TFwvvAqZaJe4iQNhwDvji92V/uRELz831J5lNi84PmY8WAqQLzWf8Uo5L2noZ/+EQiv6xydKig0hGq0WOaxSalbd6E9JYqKXRny2gAhEEIjWzhKyd4yUa4z3WOWe2r8wGTF06y6nbtTaOvVtUKWSC/0ZS9v6fxdmv37TLxZczJ1XNQpRpCPkOngz11ZYuBV0jR23VZfW//CKyV89YVufp/w6lQ74V1RCjIYb8tcIS8L8QTQB1JCqFFyUMhgOmFEYHZSF0BZYicXO78i7wK3wbZqjo0WMmySw6Yy1v1yYPB2xCFiXRCLSsiQTAPwxAghOWMdCWhx5qXTPmNbvZXOuyKQCbFPxJzjYpmPGIfI2Zhiu5Fdmx58NjcJBHNFQJ9Km0FpVb1TOpPdTaWvi6Ms6ecivzOPV9WzFtSkA5R0Hr5pBcRgGRMVkJqSEyeebJfWKhBcjNSHmTcuwCE3s/WcOAhZRzq9dnYY6cTBcMfodXMOiICU5nq9Zt5NsLFSNI+5q8bghPmfy5mQ7cobhNge1lJme6hUXV4CRTw==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
// TODO: New parameter: alternatively check for the creation timestamp instead of the modification timestamp.
// TODO: vnag soll der timestamp monitor auch warnen, wenn gewisse dateien nicht gefunden werden? im moment macht er nur einen glob() und ignoriert damit leere ergebnisse
 
declare(ticks=1);
 
class FileTimestampCheck extends VNag {
protected $argFiles = null;
 
public function __construct() {
parent::__construct();
 
$this->registerExpectedStandardArguments('Vhtwcv');
 
$this->getHelpManager()->setPluginName('check_file_timestamp');
$this->getHelpManager()->setVersion('1.0');
$this->getHelpManager()->setShortDescription('This plugin checks if local files are within a specific timestamp.');
$this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
$this->getHelpManager()->setSyntax('$SCRIPTNAME$ [-v] -w <warnSeconds>s -c <critSeconds>s -f "[#]<mask>" [-f "[#]<mask>" [...]]');
$this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
 
// Individual (non-standard) arguments:
$this->addExpectedArgument($this->argFiles = new VNagArgument('f', 'file', VNagArgument::VALUE_REQUIRED, 'mask', 'The files to be checked. This argument can be used multiple times. Wilcards may be used but MUST be passed as string only (not resolved by the Shell). There are two possible checking modes: If you put a # in front of the file mask, only the youngest file of each group will be checked (use this mode e.g. if you want to check if a downloader is regularly downloading files into a download directory). Otherwise, all files of the file group are checked.'));
 
// In this context, when the user writes "-w 60s" then he actually means "-w @60s:~" or "-w 0s:60s", so these commands allow this notation:
$this->warningSingleValueRangeBehaviors[0] = self::SINGLEVALUE_RANGE_VAL_GT_X_BAD;
$this->criticalSingleValueRangeBehaviors[0] = self::SINGLEVALUE_RANGE_VAL_GT_X_BAD;
}
 
private static function humanFriendlyInterval($secs) {
$out = array();
 
$years = floor($secs / 60 / 60 / 24 / 365);
if ($years > 0) $out[] = $years == 1 ? "$years year" : "$years years";
 
$days = floor($secs / 60 / 60 / 24) % 365;
if ($days > 0) $out[] = $days == 1 ? "$days day" : "$days days";
 
$hours = floor($secs / 60 / 60) % 24;
if ($hours > 0) $out[] = $hours == 1 ? "$hours hour" : "$hours hours";
 
$minutes = floor($secs / 60) % 60;
if ($minutes > 0) $out[] = $minutes == 1 ? "$minutes minute" : "$minutes minutes";
 
$seconds = $secs % 60;
if ($seconds > 0) $out[] = $seconds == 1 ? "$seconds second" : "$seconds seconds";
 
return implode(", ", $out);
}
 
protected function cbRun($optional_args=array()) {
$this->argFiles->require();
 
$countFilesTotal = 0;
$countFilesCrit = 0;
$countFilesWarn = 0;
 
$fileGroupMasks = $this->argFiles->getValue();
if (!is_array($fileGroupMasks)) $fileGroupMasks = array($fileGroupMasks);
foreach ($fileGroupMasks as $fileGroupMask) {
if (substr($fileGroupMask, 0, 1) === '#') {
$fileGroupMask = substr($fileGroupMask, 1); // remove #
 
// Mode 1: Only the youngest file of each group is checked.
// You can use this mode e.g. if you have a folder with downloaded files
// and you want to check if a downloading-script is still downloading
// new files regularly.
 
$files = glob($fileGroupMask);
if (count($files) == 0) continue;
 
$youngestTS = null;
foreach ($files as $file) {
$youngestTS = is_null($youngestTS) ? filemtime($file) : max($youngestTS, filemtime($file));
}
 
$youngestAge = time() - $youngestTS;
$countFilesTotal++;
if ($this->checkAgainstCriticalRange($youngestAge.'s', false, true)) {
$countFilesCrit++;
$this->addVerboseMessage("File group '$fileGroupMask': Youngest file's age: ".self::humanFriendlyInterval($youngestAge)." (Critical)\n", VNag::VERBOSITY_SUMMARY);
} else if ($this->checkAgainstWarningRange($youngestAge.'s', false, true)) {
$countFilesWarn++;
$this->addVerboseMessage("File group '$fileGroupMask': Youngest file's age: ".self::humanFriendlyInterval($youngestAge)." (Warning)\n", VNag::VERBOSITY_SUMMARY);
} else {
if (($this->getArgumentHandler()->getArgumentObj('w')->available()) || ($this->getArgumentHandler()->getArgumentObj('c')->available())) {
$this->addVerboseMessage("File group '$fileGroupMask': Youngest file's age: ".self::humanFriendlyInterval($youngestAge)." (OK)\n", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
} else {
$this->addVerboseMessage("File group '$fileGroupMask': Youngest file's age: ".self::humanFriendlyInterval($youngestAge)."\n", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
}
}
} else {
// Mode 2: All files of each group are checked.
 
$files = glob($fileGroupMask);
if (count($files) == 0) continue;
 
foreach ($files as $file) {
$age = time() - filemtime($file);
$countFilesTotal++;
if ($this->checkAgainstCriticalRange($age.'s', false, true)) {
$countFilesCrit++;
$this->addVerboseMessage("File $file age ".self::humanFriendlyInterval($age)." (Critical)\n", VNag::VERBOSITY_SUMMARY);
} else if ($this->checkAgainstWarningRange($age.'s', false, true)) {
$countFilesWarn++;
$this->addVerboseMessage("File $file age ".self::humanFriendlyInterval($age)." (Warning)\n", VNag::VERBOSITY_SUMMARY);
} else {
if (($this->getArgumentHandler()->getArgumentObj('w')->available()) || ($this->getArgumentHandler()->getArgumentObj('c')->available())) {
$this->addVerboseMessage("File $file age ".self::humanFriendlyInterval($age)." (OK)\n", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
} else {
$this->addVerboseMessage("File $file age ".self::humanFriendlyInterval($age)."\n", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
}
}
}
}
}
 
$msg = array();
$msg[] = "Checked $countFilesTotal files";
if ($this->getArgumentHandler()->getArgumentObj('w')->available()) $msg[] = "$countFilesWarn are in warning time range";
if ($this->getArgumentHandler()->getArgumentObj('c')->available()) $msg[] = "$countFilesCrit are in critical time range";
$msg = implode(", ", $msg);
 
$this->setHeadLine($msg);
}
}
/trunk/plugins/file_timestamp/check_file_timestamp
0,0 → 1,20
#!/usr/bin/php
<?php /* <ViaThinkSoftSignature>JECmzbK89A3spE9vWc+t83TbtGIVkkOPxRZGky06jmfgaJWI1OHNTowDly/6e3hXqOXPC8GhdvgkGNOm4DiqDR94Q8bSZnnnjYJ8M0wU+RqOgGOZcxtHyxYh1cMt4+Nfqiq0uh12HT7DeC133UA53/bZ9qr2zeMg7FhJV7AB7zSNlxyt3IcwS82soT0sZNVCia48Jltyqrb4LthTOJJ+DFDtSfuVNZhi4zbY7Hu7rzw6nCSLx63ZJO0EytvtLysPDHU1NDC5VQGnehZeDH//Pp/n27bcU3bk5Y9rB/lsr/cy3Ee36JoztWcHO6pdU8BtB7Ym1aXlFO2KhXG4E0vaWauAdoujDbL2gCRxDpsJsQxCEpM86mbaYbo3Fm69aJhxX/G5dVNIkXfEqfRGF99bfiPjlSNwVPJAhViYnMgZcix/BoaKlqB5OTONoD0jrhySYI5WxBDapczNp4cZv6ZpXBTTzyVxGaGbNmpCICjLfzU5em9k5VK3Dn18lo14ctOMZVdcHhNOdtqxTskIURO3X1NePMCoOTI/oofXAxAaAEWMcATK6JbqKNpP4TDY0/QAigTVClowK9+EMJHvY1oVAbOV/3etCcY91tHLJJfQfpx2M7xGrgz4Shcf3Xp/NmdxV30yz37tUVtmRtte/D9cx9M6tmS4fptWHD+L53PKYT1ul7nBcHlcX9csxOKstECV95BjJ/0qJTKmVt71TRD9VsSsQQtvEHTydabemcTYE5oYnhKpaPEQdTLnMM3yk0H+qwRB1yheZCWGt85pqxPmGkZwxBta1j6uZTec/nvWbBxJRkzZ5Oyou9IM80eNaGGD96FsOhv6i09bxxpRN0bTa5IrZK4szxnpPgW5bmQOalGom32R1KKKriuYK4brEy1jMpUZAlmN9LrphCfJZFXuVbBdWe7cWZ0F+blbrlLbTMR1LxpF1r8hlKIqhuf1OMysbkcqEA303cMdlTaUSokJw2J/bgoa22GLRW5aSpUjqjm0L6MQqu58TZT4NhB5VRXo0ORZsswI38/U8HhojJ9tSq+x39ctn0uMwI5PBXOvXbkohI2BGkwo5YqLNTOV6I2uY1cEhMlIu1zg1OcribTlCPIhd9xT91EX45AOVlOYEy36k2P3AfrOcAjiFMDfcgVQlzxjHYv1IWUfe7FZUoq5SNVMdEWVqgwqHqVaZ15KgRNlgM7pQ4uDb6Uf3RkJMLZOgi8I4uLi5pG7zAyiPC+7wSFSgEvkH36/hBHWTnCp2zjdH7gOkPD2I6ICNt02XQ72xG5+J45c5vI2VY3WCLK7VeHjdoBvGDgzVCWU3jCmUFUzt8wiupkeCkpQzh23dCFLrQkLCGMbfv96tqIC8a+jBg==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__ . '/FileTimestampCheck.class.php';
 
$job = new FileTimestampCheck();
$job->run();
unset($job);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/file_timestamp/icinga2.conf
0,0 → 1,71
// Put this file in /etc/icinga2/conf.d/...
 
// VNag - Nagios Framework for PHP
// Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
// Licensed under the terms of the Apache 2.0 license
//
// Revision 2018-07-15
 
object CheckCommand "vnag_file_timestamp" {
command = [ "/daten/vnag/plugins/file_timestamp/check_file_timestamp" ]
 
arguments = {
"-f" = {
value = "$vnag_file_timestamp_file$"
description = "File or filemask to be checked. There are two possible checking modes: If you put a # in front of the file mask, only the youngest file of each group will be checked (use this mode e.g. if you want to check if a downloader is regularly downloading files into a download directory). Otherwise, all files of the file group are checked."
repeat_key = true
required = true
}
"-w" = {
value = "$vnag_file_timestamp_warn$"
description = "Max age of file (warning range). You must use a Nagios compatible unit of measure (i.e. seconds)."
}
"-c" = {
value = "$vnag_file_timestamp_crit$"
description = "Max age of file (critical range). You must use a Nagios compatible unit of measure (i.e. seconds)."
}
"-v" = {
set_if = "$vnag_file_timestamp_verbose$"
description = "Additionally list files which are OK, not just the files which are out of the time range."
}
}
}
 
// Example usage:
//
// apply Service "example_daily_backup_timestamp" {
// import "generic-service"
// check_command = "vnag_file_timestamp"
// vars = {
// vnag_file_timestamp_file = [ "/backup/automatic/timestamps/ts_daily_rsync", "/backup/automatic/timestamps/ts_daily_mysqldump" ]
// vnag_file_timestamp_warn = "86400s" // 24h
// vnag_file_timestamp_crit = "144000s" // 40h
// vnag_file_timestamp_verbose = false
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_3month_backup_timestamp" {
// import "generic-service"
// check_command = "vnag_file_timestamp"
// vars = {
// vnag_file_timestamp_file = [ "/backup/automatic/timestamps/ts_raspberry_rsync" ]
// vnag_file_timestamp_warn = "7776000s" // 3 Months
// vnag_file_timestamp_crit = "15552000s" // 6 Months
// vnag_file_timestamp_verbose = false
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_downloader_timestamp" {
// import "generic-service"
// check_command = "vnag_file_timestamp"
// // the prepending hashtag means 'check only the youngest file'
// vars = {
// vnag_file_timestamp_file = [ "#/home/test/my_downloader/downloaded_files/*.jpg" ]
// vnag_file_timestamp_warn = "86400s" // 24h
// vnag_file_timestamp_crit = "144000s" // 40h
// vnag_file_timestamp_verbose = false
// }
// assign where host.name == NodeName
// }
/trunk/plugins/ipfm/INSTALL
0,0 → 1,23
HOW TO SETUP THIS MONITOR!
 
1. Install ipfm
 
$aptitude install ipfm
 
2. Setup ipfm (set your IP addresses and enable)
 
3. Change /etc/ipfm.conf to hourly clearing and at least hourly dumping! (OTHERWISE THIS MONITOR WON'T WORK!!!)
 
FILENAME "/var/log/ipfm/eth0/%Y_%m_%d_%H.log"
# Log every hour, but update the information every minute
DUMP EVERY 1 minute
CLEAR EVERY 1 hour
SORT TOTAL
RESOLVE
 
4. Create following crontab entry to delete log files which are older than 370 days:
 
0 0 1 1 * find /var/log/ipfm/eth0 -name "20??_??_??_??.log" -mtime +370 -exec /bin/rm -f {} \;
 
5. In case you are using Icinga2, install icinga2.conf into /etc/icinga2/conf.d/
Please make sure to edit the path of your command.
/trunk/plugins/ipfm/IpFlowMonitorCheck.class.php
0,0 → 1,319
<?php /* <ViaThinkSoftSignature>bVXNXMFkwzws1bw2aTgNQAwu+mCcFkvvhz9FqAKANysqdqSs9FdBjBYSFz7gAW9QyfvDHVfMUs+KcUOru3hgfNToru2AH8y/MAY2yTttNH1drSoKqcFPB0ciqLPt4kQ2kUEqMlFQLtU5Db4Op6ynEpr4b18N3Rpqia0BkdjmfVtJ2Z/q37hMkXkkGYmUXvezGaWuRvfRtTaUkO/G4Dn7XvcHyhiqAqP2YxHAWyNzhC3NV+UkeistXS+3RNDqEthuV/3TjXGGcxGbsXhMAKuZTwCuFnlRoHdHd5zanlyQtMzSSmqS/AhOVgoXFQMgNQgnf24XAtx+GOM55Bgr6hCaDruIE7HpIJ6fKuUU4MiRCTb6IDoeDo71HqZJCn2j4W5jbAFtx88P+jw4wdbhUt1CiCA2zobgnGkEBAZDhafjTS8xLz0mpBWe09aHVxbqKifKBw80w224LlnmiusrsuJCknOJkSnHrCQbccFwSmqDJS3nPGnreZpZG+wJ/vqI9sQhbLtw5tD81eaQoilL6pYmzVqAD2yXBDOjpYOZaxeHQX+rVYPIOle1Sbj7P/1ZeVdf+NENtmiSXA2kdLlDJlqT7l+/+47Dqyh2ebGZND0eB4IAVWqNFT0ofYu0XAuHujf+eFo67Hc/xUEihf5+Jzk/xM6MMhDbrU+drqWoz2mRC3sCGhKgzE/11h04yquozyhZtmxo6ZpdYiib+ttCNmObxa920aB4KPgZzhNfky+oCGPiYTlY+lR42chCxITHRatm4ohK9grUlUwvE8HBgHgXgGQSDZdG9+CjuU/DKz5xyRIuEVz2pAoQNwWVntGz1rgPFe5InljAwNgoVxRYyo3NtRFyxs60QuXwaXLOF4a6lLrTwIMMAMrbq0F1nkdDBRCz39E/60D7I9MQ3yZxwG0Vwi0RDrZRMTBbLDF05haKsdR0hFefoHjMpXi1kuNwRbKPRq+A+3oz+RqK0YNEqIN0K4R3iJ4jqO3EduWKhWxkXIgC2KZngVJqnuB/UWITc43Ge9+32ffjCRC71iK8FzX7i2kn5FSrIiSAU7S99at6AqhM5GgE/rRqmRgZHMte0io4cksGSp9tgsbH22/WK3tlCiJHWwu3JnDhRnI1+aELcBwHUuGoiwB+D0bkpJPXk9yaDJzcdEvskzA4zbOrdNDRPvjwxoAIGUx9gxfNUXDBafXyp6nAwGpm5obK08Kzsve9hU6iO+TAna0wuCptVWC+/ZKeBU+WvYQGntndRJrEntKftUzUsj0Vde8Bc8qcSxWSIgiT1aWsu6TYfMDniKlnWq+SSv3pc1BJX6YdGOgcorgbqLE+sqpQLMqWwwD0vzcC/7LTivSdrIqogz5NOLti2w==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-19
*/
 
# IMPORTANT
# The log files have to be named YYYY_MM_DD_HH.log and need to be cleared (zeroed) every hour and dumped at least every hour (every minute is also possible)
# Please see the file INSTALL
 
# ---
 
# TODO: trennen zwischen server (ip1, ip2) ermöglichen...
# TODO: prüfen lassen ob die config von ipfm korrekt ist (dumped every 1 hour)
# TODO: monat vor/zurückscrollen? (mon/year)
# TODO: anstelle "year .... overview" lieber "last 12 months"
# TODO: Some hosts might reset the traffic counter at any other day of the month. Should we also support this?
 
# ---
 
declare(ticks=1);
 
# Attention: This constant must be a valid Nagios UOM!
# TODO: Make it configurable via command line? Should we use the UOM from the w/c/l arguments?
define('OUTPUT_UOM', 'GB');
 
# ---
 
class IpFlowMonitorCheck extends VNag {
protected $argLogDir = null;
protected $argLimit = null;
 
public function __construct() {
parent::__construct();
 
$this->registerExpectedStandardArguments('Vhtwc');
 
$this->getHelpManager()->setPluginName('check_ipfm');
$this->getHelpManager()->setVersion('1.0');
$this->getHelpManager()->setShortDescription('This plugin checks the network traffic monitored by ipfm.');
$this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
$this->getHelpManager()->setSyntax('$SCRIPTNAME$ [-w currentGB[,expectedGB]] [-c currentGB[,expectedGB]] [-l limitGB] [-L path]');
$this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
 
// This is the amount of traffic which is free. Every byte above this limit will cost additional money.
// You should therefore set your warning and critical limit below this limit.
// Don't set this argument if you have an unlimited connection.
// This value is only for visual output. It does not influence the OK/Warning/Critial result.
$this->addExpectedArgument($this->argLimit = new VNagArgument('l', 'limit', VNagArgument::VALUE_REQUIRED, 'limit', '"Traffic inclusive" limit (e.g. 10TB)', null));
 
$this->addExpectedArgument($this->argLogDir = new VNagArgument('L', 'logdir', VNagArgument::VALUE_REQUIRED, 'path', 'Location of the ipfm log dir (Default: /var/log/ipfm)', '/var/log/ipfm'));
 
// When the user writes "-w 10GB" then he actually means "-w @10GB:~" or "-w ~:10GB", so these commands allow this notation:
$this->warningSingleValueRangeBehaviors[0] = self::SINGLEVALUE_RANGE_VAL_GT_X_BAD;
$this->warningSingleValueRangeBehaviors[1] = self::SINGLEVALUE_RANGE_VAL_GT_X_BAD;
$this->criticalSingleValueRangeBehaviors[0] = self::SINGLEVALUE_RANGE_VAL_GT_X_BAD;
$this->criticalSingleValueRangeBehaviors[1] = self::SINGLEVALUE_RANGE_VAL_GT_X_BAD;
}
 
protected function interprete_ipfm_logfile($logfile) {
$res = array();
 
$ary = file($logfile);
foreach ($ary as $a) {
$a = trim($a);
if ($a == '') continue;
if (substr($a, 0, 1) == '#') continue;
$a = preg_replace("|\s+|ism", ' ', $a);
$bry = explode(' ', $a);
$res[$bry[0]] = array($bry[1], $bry[2], $bry[3]);
}
 
return $res;
}
 
protected function cbRun($optional_args=array()) {
if (!defined('USE_DYGRAPH')) define('USE_DYGRAPH', false);
 
$logDir = $this->argLogDir->getValue();
if (!is_dir($logDir)) throw new Exception("Log dir $logDir not found");
 
$monthLimit = $this->argLimit->getValue();
if (!is_null($monthLimit)) {
$p = (new VNagValueUomPair($monthLimit))->normalize(OUTPUT_UOM);
$monthLimitValue = $p->getValue();
$monthLimitUom = $p->getUom();
}
 
ob_start();
 
?>
 
<script type="text/javascript">
google.load("visualization", "1", {packages:['imageareachart', 'corechart']});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Year');
data.addColumn('number', 'Total');
data.addColumn('number', 'In');
data.addRows([
 
<?php
 
$day = date('d');
$mon = date('m');
$year = date('Y');
 
$didata = '';
$logfiles = glob($logDir.'/*.log');
sort($logfiles);
 
$monthtotal[$year][$mon] = 0;
$daystotal = array();
$max = 0;
$first = true;
foreach ($logfiles as $logfile) {
$stat = $this->interprete_ipfm_logfile($logfile);
 
$date = '';
if (preg_match('/^.*_00\.log$/', $logfile)) {
preg_match('@(\d{4})_(\d{2})_(\d{2})@ismU', $logfile, $m);
$t_day = $m[3];
$t_mon = $m[2];
$t_year = $m[1];
// $date = "$t_day.$t_mon.$t_year";
$date = $t_day;
//} else if (preg_match('/^.*_(02|04|06|08|10|12|14|16|18|20|22)\.log$/', $logfile, $m)) {
// $date = $m[1].':00';
}
 
$in = $out = $total = 0;
foreach ($stat as $s) {
$in += $s[0];
$out += $s[1];
$total += $s[2];
}
 
$in = (new VNagValueUomPair($in.'B'))->normalize(OUTPUT_UOM)->getValue();
$out = (new VNagValueUomPair($out.'B'))->normalize(OUTPUT_UOM)->getValue();
$total = (new VNagValueUomPair($total.'B'))->normalize(OUTPUT_UOM)->getValue();
 
if (preg_match('/^.*(\d{4})_(\d{2})_(\d{2})_(\d{2})\.log$/', $logfile, $m)) {
$t_year = $m[1];
$t_mon = $m[2];
$t_day = $m[3];
$t_hour = $m[4];
if (isset($monthtotal[$t_year][$t_mon])) {
$monthtotal[$t_year][$t_mon] += $total;
} else {
$monthtotal[$t_year][$t_mon] = $total;
}
 
if (($t_year == $year) && ($t_mon == $mon)) {
if (isset($daystotal[$t_day])) {
$daystotal[$t_day] += $total;
} else {
$daystotal[$t_day] = $total;
}
if (!$first) echo ","; else $first = false;
echo "['$date', ".round($total,2).", ".round($in,2)."]\n";
$didata .= '"'.$t_year.'-'.$t_mon.'-'.$t_day.' '.$t_hour.':00:00,'.round($in,2).','.round($out,2).','.round($total,2).'\n" +'."\n";
}
}
 
if ($total > $max) $max = $total;
}
 
$num_days_in_month = date('t', mktime(0, 0, 0, $mon, 1, $year));
$expected = $monthtotal[$year][$mon]/$day * $num_days_in_month;
 
?>
]);
 
var chart = new google.visualization.ImageAreaChart(document.getElementById('chart_div'));
<?php if (!USE_DYGRAPH) { ?>
chart.draw(data, {width: 800, height: 440, min: 0, max: <?php echo $max; ?>, title: 'Traffic in <?php echo $mon.'/'.$year; ?> [in <?php echo OUTPUT_UOM; ?>/h]'});
<?php } ?>
 
// ---
 
var data_month = new google.visualization.DataTable();
data_month.addColumn('string', 'Day');
data_month.addColumn('number', 'Total');
 
data_month.addRows([
<?php
 
$first = true;
foreach ($daystotal as $t_day => $traffic) {
if (!$first) echo ","; else $first = false;
echo "['$t_day.$mon.$year', ".round($traffic,2)."]\n";
}
 
?>
]);
 
var options_month = {
width: 800, height: 440,
vAxis: { viewWindow: { min: 0 } },
title: 'Month overview for <?php echo $mon.'/'.$year; ?> [GiB]'
};
 
var chart_month = new google.visualization.ColumnChart(document.getElementById('chart_div3'));
chart_month.draw(data_month, options_month);
 
// ---
 
var data_year = new google.visualization.DataTable();
data_year.addColumn('string', 'Month/Year');
data_year.addColumn('number', 'Total');
 
data_year.addRows([
<?php
 
ksort($monthtotal); // First sort by year
 
$first = true;
foreach ($monthtotal as $t_year => $x) {
ksort($x); // Then sort by month
foreach ($x as $t_mon => $traffic) {
if ($t_year != $year) continue; // Only this year
 
$date = "$t_mon/$t_year";
 
if (!$first) echo ","; else $first = false;
echo "['$date', ".round($traffic,2)."]\n";
}
echo ",['Expected in $mon/$year', $expected]\n";
}
 
?>
]);
 
var options_year = {
width: 800, height: 440,
vAxis: { viewWindow: { min: 0 } },
title: 'Year <?php echo $year; ?> overview [GiB]'
};
 
var chart_year = new google.visualization.ColumnChart(document.getElementById('chart_div2'));
chart_year.draw(data_year, options_year);
}
 
</script>
 
<?php if (USE_DYGRAPH) { ?>
<script type="text/javascript">
g = new Dygraph(
document.getElementById("graphdiv"),
"Date,In,Out,Total\n" +
<?php echo $didata; ?>""
);
</script>
<?php } ?>
 
<?php
 
if (!is_null($monthLimit)) {
echo "<p>Constraint: Max ".$monthLimitValue.' '.OUTPUT_UOM."/Month</p>";
}
 
$current = $monthtotal[$year][$mon];
 
$fontcolor = 'green';
if ($this->checkAgainstCriticalRange($current.OUTPUT_UOM, false, true, 0)) $fontcolor = 'red';
if ($this->checkAgainstWarningRange($current.OUTPUT_UOM, false, true, 0)) $fontcolor = '#FF8000';
 
if (!is_null($monthLimit)) {
echo "<p>This month ($mon/$year): <font color=\"$fontcolor\">".round($current,0)." ".OUTPUT_UOM." (".round($current/$monthLimitValue*100,2)."%)</font></p>";
} else {
echo "<p>This month ($mon/$year): <font color=\"$fontcolor\">".round($current,0)." ".OUTPUT_UOM."</font></p>";
}
 
$fontcolor = 'green';
if ($this->checkAgainstCriticalRange($expected.OUTPUT_UOM, false, true, 1)) $fontcolor = 'red';
if ($this->checkAgainstWarningRange($expected.OUTPUT_UOM, false, true, 1)) $fontcolor = '#FF8000';
 
if (!is_null($monthLimit)) {
echo "<p>Expected for this month: <font color=\"$fontcolor\">".round($expected,0)." ".OUTPUT_UOM." (".round($expected/$monthLimitValue*100,2)."%)</font></p>";
} else {
echo "<p>Expected for this month: <font color=\"$fontcolor\">".round($expected,0)." ".OUTPUT_UOM."</font></p>";
}
 
?>
 
<div id="chart_div"></div>
<div id="graphdiv"></div>
<div id="chart_div3"></div>
<div id="chart_div2"></div>
 
<?php
 
$html = ob_get_contents();
ob_end_clean();
 
$this->outputHTML($html, true);
 
if (!is_null($monthLimit)) {
// TODO: should we put a percentage at "expected"? or if it exceeds, should we show how much it would exceed?
$this->setHeadline(round($current,0).' '.OUTPUT_UOM." / ".$monthLimitValue.' '.OUTPUT_UOM." (".round($current/$monthLimitValue*100,2)."%, expected ".round($expected,0).' '.OUTPUT_UOM.") traffic used this month ($mon/$year)", true);
} else {
$this->setHeadline(round($current,0).' '.OUTPUT_UOM." (expected ".round($expected,0).' '.OUTPUT_UOM.") traffic used this month ($mon/$year)", true);
}
 
$warn = is_null($this->getWarningRange(0)) ? null : $this->getWarningRange(0)->end->normalize(OUTPUT_UOM)->getValue();
$crit = is_null($this->getCriticalRange(0)) ? null : $this->getCriticalRange(0)->end->normalize(OUTPUT_UOM)->getValue();
$this->addPerformanceData(new VNagPerformanceData('Current', $current.OUTPUT_UOM, $warn, $crit, 0, is_null($monthLimit) ? null : $monthLimitValue));
 
$warn = is_null($this->getWarningRange(1)) ? null : $this->getWarningRange(1)->end->normalize(OUTPUT_UOM)->getValue();
$crit = is_null($this->getCriticalRange(1)) ? null : $this->getCriticalRange(1)->end->normalize(OUTPUT_UOM)->getValue();
$this->addPerformanceData(new VNagPerformanceData('Expected', $expected.OUTPUT_UOM, $warn, $crit, 0, is_null($monthLimit) ? null : $monthLimitValue));
}
}
/trunk/plugins/ipfm/check_ipfm
0,0 → 1,20
#!/usr/bin/php
<?php /* <ViaThinkSoftSignature>i1ENnhHvxxfsQdgGuxzUctpQ75fXgEqBsKxZcAaqnRgDOijovk1qAhXZ9r9FlDmOz1gzir6hsfSvp6GbZ0o7w4epX4mH2jfvOSHGZ42kAvm8kemY0or/t5cXlrtPuR3jVJ7Nyp7uKGIZCI9cl/MT6m86IpTDarL36FijdnqAfQdWimYC2DGDjMaY8UfAW4rHPaQvDPsoq6g2i4WrSZe8YrohwMM1hJceSX+VCqfV8CBOIGgdpmU7WroNitZV9W6t7c2UkbsgwiRfA9TcKj4Q+QOkD0Z+ovPlDOzlU0K+4EF+gE/n+1wBHro5yJtM3kAiBBuNUsYwu/Zgo436UwF7FrjF3xRNpW0IGUKeslEKGy/ifnxcAuekan21hE5s3HRCkK2rN3N1oT9JqQwcWHxWD/zwmy2KApv/+8h311D39vsftljOkelowcwwiOgILmQrQsPGPzLjyJC+QSGc6z5l/HBD5yWYZqGRZZG1YSip7zZaOvO0RqW191vb7l77FQnbPi6nhftY2Y5tTkzUuZR8TWIqn7I3RBKwzEUhPiaF3GhAYgDNmFzV/AXJnMolg1oH1AyZlcNkEm60w/xA7AdlVVPJvy09r7wNpYv/HbdZizWV97kKiV8m3qJFLWjU6fOxJR4CQATMG3qTDJ/B6EBKgr/HT3beyk5FJM0zXDEoR92A/c6mnBV2KSRtJkJM5cBO4rJIdgBIKgcnag+Drl0u1GvjwtUeq2CBwaIk4ZpqLpSFXaNIC/Hh5ItfY7MTy1+Vh5LA+2I+T0IsU+pEw6tpFDa1ghlLQ0HSI9WMV0G2/8YmHgkw6lgzRBOBD64kOQUwFRfvSwh/cHrPpOSbsp2WlDsfaqlSizYcFuHfAsY79/iI8xBxINL8CdVCkypB+TycQnTrP4Mf4W8BsHLFtslCEE/r5wZ3t5ngkpR5l8CpXtQDd8UopAHtFOVqwmNEePx2z0gvER7IX6QEVDy3CMbgLI+9uBTt1DpK80t8xKzyF6Al5Tx8o1bp61yIjfjM9CQPfhRgLaSLhGoP5U3F97etqrD++RDTPt6l2aqUb8tjkmEMyIbGW/EWFPsddBjqWfiE5Ivo8Q0ypbQq1SjQUjoWNADcSOo+c4TcYFMpCJLGAzCX+brozc1K2u4/FZGYUmvddQy1bGVPPrh7fteFhZ0mG6I9x5bvwe8d+iCy70Iibzi24htd+EafF9flYa7aU5UkUM29ybC09DvAnwJmxaYgdtstZ5nl5stQNGatCQdhFFFU4a+CPYFCHVAXrsHwmpSvDAbaVJhAglYR2kw3oUs7dydTZplOtAkbZYa6lDf0gYM8ALSAPy7MMZ8gkkm/rt0cA/wAhuyy6uLuQGsQZSqh+Q==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-19
*/
 
declare(ticks=1);
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__ . '/IpFlowMonitorCheck.class.php';
 
$job = new IpFlowMonitorCheck();
$job->run();
unset($job);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/ipfm/dygraph/dygraph-combined.js
0,0 → 1,0
"use strict";var DygraphLayout=function(a){this.dygraph_=a;this.datasets=[];this.annotations=[];this.yAxes_=null;this.xTicks_=null;this.yTicks_=null};DygraphLayout.prototype.attr_=function(a){return this.dygraph_.attr_(a)};DygraphLayout.prototype.addDataset=function(a,b){this.datasets[a]=b};DygraphLayout.prototype.getPlotArea=function(){return this.computePlotArea_()};DygraphLayout.prototype.computePlotArea_=function(){var a={x:0,y:0};if(this.attr_("drawYAxis")){a.x=this.attr_("yAxisLabelWidth")+2*this.attr_("axisTickSize")}a.w=this.dygraph_.width_-a.x-this.attr_("rightGap");a.h=this.dygraph_.height_;if(this.attr_("drawXAxis")){if(this.attr_("xAxisHeight")){a.h-=this.attr_("xAxisHeight")}else{a.h-=this.attr_("axisLabelFontSize")+2*this.attr_("axisTickSize")}}if(this.dygraph_.numAxes()==2){a.w-=(this.attr_("yAxisLabelWidth")+2*this.attr_("axisTickSize"))}else{if(this.dygraph_.numAxes()>2){this.dygraph_.error("Only two y-axes are supported at this time. (Trying to use "+this.dygraph_.numAxes()+")")}}if(this.attr_("title")){a.h-=this.attr_("titleHeight");a.y+=this.attr_("titleHeight")}if(this.attr_("xlabel")){a.h-=this.attr_("xLabelHeight")}if(this.attr_("ylabel")){}if(this.attr_("y2label")){}if(this.attr_("showRangeSelector")){a.h-=this.attr_("rangeSelectorHeight")+4}return a};DygraphLayout.prototype.setAnnotations=function(d){this.annotations=[];var e=this.attr_("xValueParser")||function(a){return a};for(var c=0;c<d.length;c++){var b={};if(!d[c].xval&&!d[c].x){this.dygraph_.error("Annotations must have an 'x' property");return}if(d[c].icon&&!(d[c].hasOwnProperty("width")&&d[c].hasOwnProperty("height"))){this.dygraph_.error("Must set width and height when setting annotation.icon property");return}Dygraph.update(b,d[c]);if(!b.xval){b.xval=e(b.x)}this.annotations.push(b)}};DygraphLayout.prototype.setXTicks=function(a){this.xTicks_=a};DygraphLayout.prototype.setYAxes=function(a){this.yAxes_=a};DygraphLayout.prototype.setDateWindow=function(a){this.dateWindow_=a};DygraphLayout.prototype.evaluate=function(){this._evaluateLimits();this._evaluateLineCharts();this._evaluateLineTicks();this._evaluateAnnotations()};DygraphLayout.prototype._evaluateLimits=function(){this.minxval=this.maxxval=null;if(this.dateWindow_){this.minxval=this.dateWindow_[0];this.maxxval=this.dateWindow_[1]}else{for(var c in this.datasets){if(!this.datasets.hasOwnProperty(c)){continue}var e=this.datasets[c];if(e.length>1){var b=e[0][0];if(!this.minxval||b<this.minxval){this.minxval=b}var a=e[e.length-1][0];if(!this.maxxval||a>this.maxxval){this.maxxval=a}}}}this.xrange=this.maxxval-this.minxval;this.xscale=(this.xrange!==0?1/this.xrange:1);for(var d=0;d<this.yAxes_.length;d++){var f=this.yAxes_[d];f.minyval=f.computedValueRange[0];f.maxyval=f.computedValueRange[1];f.yrange=f.maxyval-f.minyval;f.yscale=(f.yrange!==0?1/f.yrange:1);if(f.g.attr_("logscale")){f.ylogrange=Dygraph.log10(f.maxyval)-Dygraph.log10(f.minyval);f.ylogscale=(f.ylogrange!==0?1/f.ylogrange:1);if(!isFinite(f.ylogrange)||isNaN(f.ylogrange)){f.g.error("axis "+d+" of graph at "+f.g+" can't be displayed in log scale for range ["+f.minyval+" - "+f.maxyval+"]")}}}};DygraphLayout._calcYNormal=function(a,b){if(a.logscale){return 1-((Dygraph.log10(b)-Dygraph.log10(a.minyval))*a.ylogscale)}else{return 1-((b-a.minyval)*a.yscale)}};DygraphLayout.prototype._evaluateLineCharts=function(){this.points=[];this.setPointsLengths=[];for(var f in this.datasets){if(!this.datasets.hasOwnProperty(f)){continue}var b=this.datasets[f];var a=this.dygraph_.axisPropertiesForSeries(f);var g=0;for(var d=0;d<b.length;d++){var l=b[d];var c=parseFloat(l[0]);var h=parseFloat(l[1]);var k=(c-this.minxval)*this.xscale;var e=DygraphLayout._calcYNormal(a,h);var i={x:k,y:e,xval:c,yval:h,name:f};this.points.push(i);g+=1}this.setPointsLengths.push(g)}};DygraphLayout.prototype._evaluateLineTicks=function(){var d,c,b,f;this.xticks=[];for(d=0;d<this.xTicks_.length;d++){c=this.xTicks_[d];b=c.label;f=this.xscale*(c.v-this.minxval);if((f>=0)&&(f<=1)){this.xticks.push([f,b])}}this.yticks=[];for(d=0;d<this.yAxes_.length;d++){var e=this.yAxes_[d];for(var a=0;a<e.ticks.length;a++){c=e.ticks[a];b=c.label;f=this.dygraph_.toPercentYCoord(c.v,d);if((f>=0)&&(f<=1)){this.yticks.push([d,f,b])}}}};DygraphLayout.prototype.evaluateWithError=function(){this.evaluate();if(!(this.attr_("errorBars")||this.attr_("customBars"))){return}var g=0;for(var k in this.datasets){if(!this.datasets.hasOwnProperty(k)){continue}var f=0;var e=this.datasets[k];var d=this.dygraph_.axisPropertiesForSeries(k);for(f=0;f<e.length;f++,g++){var n=e[f];var b=parseFloat(n[0]);var l=parseFloat(n[1]);if(b==this.points[g].xval&&l==this.points[g].yval){var h=parseFloat(n[2]);var c=parseFloat(n[3]);var m=l-h;var a=l+c;this.points[g].y_top=DygraphLayout._calcYNormal(d,m);this.points[g].y_bottom=DygraphLayout._calcYNormal(d,a)}}}};DygraphLayout.prototype._evaluateAnnotations=function(){var d;var f={};for(d=0;d<this.annotations.length;d++){var b=this.annotations[d];f[b.xval+","+b.series]=b}this.annotated_points=[];if(!this.annotations||!this.annotations.length){return}for(d=0;d<this.points.length;d++){var e=this.points[d];var c=e.xval+","+e.name;if(c in f){e.annotation=f[c];this.annotated_points.push(e)}}};DygraphLayout.prototype.removeAllDatasets=function(){delete this.datasets;this.datasets=[]};DygraphLayout.prototype.unstackPointAtIndex=function(b){var a=this.points[b];var d={};for(var e in a){d[e]=a[e]}if(!this.attr_("stackedGraph")){return d}for(var c=b+1;c<this.points.length;c++){if(this.points[c].xval==a.xval){d.yval-=this.points[c].yval;break}}return d};"use strict";var DygraphCanvasRenderer=function(d,c,b,e){this.dygraph_=d;this.layout=e;this.element=c;this.elementContext=b;this.container=this.element.parentNode;this.height=this.element.height;this.width=this.element.width;if(!this.isIE&&!(DygraphCanvasRenderer.isSupported(this.element))){throw"Canvas is not supported."}this.xlabels=[];this.ylabels=[];this.annotations=[];this.chartLabels={};this.area=e.getPlotArea();this.container.style.position="relative";this.container.style.width=this.width+"px";if(this.dygraph_.isUsingExcanvas_){this._createIEClipArea()}else{if(!Dygraph.isAndroid()){var a=this.dygraph_.canvas_ctx_;a.beginPath();a.rect(this.area.x,this.area.y,this.area.w,this.area.h);a.clip();a=this.dygraph_.hidden_ctx_;a.beginPath();a.rect(this.area.x,this.area.y,this.area.w,this.area.h);a.clip()}}};DygraphCanvasRenderer.prototype.attr_=function(a){return this.dygraph_.attr_(a)};DygraphCanvasRenderer.prototype.clear=function(){var c;if(this.isIE){try{if(this.clearDelay){this.clearDelay.cancel();this.clearDelay=null}c=this.elementContext}catch(f){return}}c=this.elementContext;c.clearRect(0,0,this.width,this.height);function a(g){for(var e=0;e<g.length;e++){var h=g[e];if(h.parentNode){h.parentNode.removeChild(h)}}}a(this.xlabels);a(this.ylabels);a(this.annotations);for(var b in this.chartLabels){if(!this.chartLabels.hasOwnProperty(b)){continue}var d=this.chartLabels[b];if(d.parentNode){d.parentNode.removeChild(d)}}this.xlabels=[];this.ylabels=[];this.annotations=[];this.chartLabels={}};DygraphCanvasRenderer.isSupported=function(f){var b=null;try{if(typeof(f)=="undefined"||f===null){b=document.createElement("canvas")}else{b=f}b.getContext("2d")}catch(c){var d=navigator.appVersion.match(/MSIE (\d\.\d)/);var a=(navigator.userAgent.toLowerCase().indexOf("opera")!=-1);if((!d)||(d[1]<6)||(a)){return false}return true}return true};DygraphCanvasRenderer.prototype.setColors=function(a){this.colorScheme_=a};DygraphCanvasRenderer.prototype.render=function(){var b=this.elementContext;function c(h){return Math.round(h)+0.5}function g(h){return Math.round(h)-0.5}if(this.attr_("underlayCallback")){this.attr_("underlayCallback")(b,this.area,this.dygraph_,this.dygraph_)}var a,f,d,e;if(this.attr_("drawYGrid")){e=this.layout.yticks;b.save();b.strokeStyle=this.attr_("gridLineColor");b.lineWidth=this.attr_("gridLineWidth");for(d=0;d<e.length;d++){if(e[d][0]!==0){continue}a=c(this.area.x);f=g(this.area.y+e[d][1]*this.area.h);b.beginPath();b.moveTo(a,f);b.lineTo(a+this.area.w,f);b.closePath();b.stroke()}}if(this.attr_("drawXGrid")){e=this.layout.xticks;b.save();b.strokeStyle=this.attr_("gridLineColor");b.lineWidth=this.attr_("gridLineWidth");for(d=0;d<e.length;d++){a=c(this.area.x+e[d][0]*this.area.w);f=g(this.area.y+this.area.h);b.beginPath();b.moveTo(a,f);b.lineTo(a,this.area.y);b.closePath();b.stroke()}}this._renderLineChart();this._renderAxis();this._renderChartLabels();this._renderAnnotations()};DygraphCanvasRenderer.prototype._createIEClipArea=function(){var g="dygraph-clip-div";var f=this.dygraph_.graphDiv;for(var e=f.childNodes.length-1;e>=0;e--){if(f.childNodes[e].className==g){f.removeChild(f.childNodes[e])}}var c=document.bgColor;var d=this.dygraph_.graphDiv;while(d!=document){var a=d.currentStyle.backgroundColor;if(a&&a!="transparent"){c=a;break}d=d.parentNode}function b(j){if(j.w===0||j.h===0){return}var i=document.createElement("div");i.className=g;i.style.backgroundColor=c;i.style.position="absolute";i.style.left=j.x+"px";i.style.top=j.y+"px";i.style.width=j.w+"px";i.style.height=j.h+"px";f.appendChild(i)}var h=this.area;b({x:0,y:0,w:h.x,h:this.height});b({x:h.x,y:0,w:this.width-h.x,h:h.y});b({x:h.x+h.w,y:0,w:this.width-h.x-h.w,h:this.height});b({x:h.x,y:h.y+h.h,w:this.width-h.x,h:this.height-h.h-h.y})};DygraphCanvasRenderer.prototype._renderAxis=function(){if(!this.attr_("drawXAxis")&&!this.attr_("drawYAxis")){return}function q(i){return Math.round(i)+0.5}function p(i){return Math.round(i)-0.5}var d=this.elementContext;var l,n,m,s,r;var a={position:"absolute",fontSize:this.attr_("axisLabelFontSize")+"px",zIndex:10,color:this.attr_("axisLabelColor"),width:this.attr_("axisLabelWidth")+"px",lineHeight:"normal",overflow:"hidden"};var g=function(i,v,w){var x=document.createElement("div");for(var u in a){if(a.hasOwnProperty(u)){x.style[u]=a[u]}}var t=document.createElement("div");t.className="dygraph-axis-label dygraph-axis-label-"+v+(w?" dygraph-axis-label-"+w:"");t.appendChild(document.createTextNode(i));x.appendChild(t);return x};d.save();d.strokeStyle=this.attr_("axisLineColor");d.lineWidth=this.attr_("axisLineWidth");if(this.attr_("drawYAxis")){if(this.layout.yticks&&this.layout.yticks.length>0){var b=this.dygraph_.numAxes();for(r=0;r<this.layout.yticks.length;r++){s=this.layout.yticks[r];if(typeof(s)=="function"){return}n=this.area.x;var j=1;var c="y1";if(s[0]==1){n=this.area.x+this.area.w;j=-1;c="y2"}m=this.area.y+s[1]*this.area.h;l=g(s[2],"y",b==2?c:null);var o=(m-this.attr_("axisLabelFontSize")/2);if(o<0){o=0}if(o+this.attr_("axisLabelFontSize")+3>this.height){l.style.bottom="0px"}else{l.style.top=o+"px"}if(s[0]===0){l.style.left=(this.area.x-this.attr_("yAxisLabelWidth")-this.attr_("axisTickSize"))+"px";l.style.textAlign="right"}else{if(s[0]==1){l.style.left=(this.area.x+this.area.w+this.attr_("axisTickSize"))+"px";l.style.textAlign="left"}}l.style.width=this.attr_("yAxisLabelWidth")+"px";this.container.appendChild(l);this.ylabels.push(l)}var h=this.ylabels[0];var e=this.attr_("axisLabelFontSize");var k=parseInt(h.style.top,10)+e;if(k>this.height-e){h.style.top=(parseInt(h.style.top,10)-e/2)+"px"}}d.beginPath();d.moveTo(q(this.area.x),p(this.area.y));d.lineTo(q(this.area.x),p(this.area.y+this.area.h));d.closePath();d.stroke();if(this.dygraph_.numAxes()==2){d.beginPath();d.moveTo(p(this.area.x+this.area.w),p(this.area.y));d.lineTo(p(this.area.x+this.area.w),p(this.area.y+this.area.h));d.closePath();d.stroke()}}if(this.attr_("drawXAxis")){if(this.layout.xticks){for(r=0;r<this.layout.xticks.length;r++){s=this.layout.xticks[r];n=this.area.x+s[0]*this.area.w;m=this.area.y+this.area.h;l=g(s[1],"x");l.style.textAlign="center";l.style.top=(m+this.attr_("axisTickSize"))+"px";var f=(n-this.attr_("axisLabelWidth")/2);if(f+this.attr_("axisLabelWidth")>this.width){f=this.width-this.attr_("xAxisLabelWidth");l.style.textAlign="right"}if(f<0){f=0;l.style.textAlign="left"}l.style.left=f+"px";l.style.width=this.attr_("xAxisLabelWidth")+"px";this.container.appendChild(l);this.xlabels.push(l)}}d.beginPath();d.moveTo(q(this.area.x),p(this.area.y+this.area.h));d.lineTo(q(this.area.x+this.area.w),p(this.area.y+this.area.h));d.closePath();d.stroke()}d.restore()};DygraphCanvasRenderer.prototype._renderChartLabels=function(){var d,a;if(this.attr_("title")){d=document.createElement("div");d.style.position="absolute";d.style.top="0px";d.style.left=this.area.x+"px";d.style.width=this.area.w+"px";d.style.height=this.attr_("titleHeight")+"px";d.style.textAlign="center";d.style.fontSize=(this.attr_("titleHeight")-8)+"px";d.style.fontWeight="bold";a=document.createElement("div");a.className="dygraph-label dygraph-title";a.innerHTML=this.attr_("title");d.appendChild(a);this.container.appendChild(d);this.chartLabels.title=d}if(this.attr_("xlabel")){d=document.createElement("div");d.style.position="absolute";d.style.bottom=0;d.style.left=this.area.x+"px";d.style.width=this.area.w+"px";d.style.height=this.attr_("xLabelHeight")+"px";d.style.textAlign="center";d.style.fontSize=(this.attr_("xLabelHeight")-2)+"px";a=document.createElement("div");a.className="dygraph-label dygraph-xlabel";a.innerHTML=this.attr_("xlabel");d.appendChild(a);this.container.appendChild(d);this.chartLabels.xlabel=d}var c=this;function b(h,g,f){var i={left:0,top:c.area.y,width:c.attr_("yLabelWidth"),height:c.area.h};d=document.createElement("div");d.style.position="absolute";if(h==1){d.style.left=i.left}else{d.style.right=i.left}d.style.top=i.top+"px";d.style.width=i.width+"px";d.style.height=i.height+"px";d.style.fontSize=(c.attr_("yLabelWidth")-2)+"px";var e=document.createElement("div");e.style.position="absolute";e.style.width=i.height+"px";e.style.height=i.width+"px";e.style.top=(i.height/2-i.width/2)+"px";e.style.left=(i.width/2-i.height/2)+"px";e.style.textAlign="center";var j="rotate("+(h==1?"-":"")+"90deg)";e.style.transform=j;e.style.WebkitTransform=j;e.style.MozTransform=j;e.style.OTransform=j;e.style.msTransform=j;if(typeof(document.documentMode)!=="undefined"&&document.documentMode<9){e.style.filter="progid:DXImageTransform.Microsoft.BasicImage(rotation="+(h==1?"3":"1")+")";e.style.left="0px";e.style.top="0px"}a=document.createElement("div");a.className=g;a.innerHTML=f;e.appendChild(a);d.appendChild(e);return d}var d;if(this.attr_("ylabel")){d=b(1,"dygraph-label dygraph-ylabel",this.attr_("ylabel"));this.container.appendChild(d);this.chartLabels.ylabel=d}if(this.attr_("y2label")&&this.dygraph_.numAxes()==2){d=b(2,"dygraph-label dygraph-y2label",this.attr_("y2label"));this.container.appendChild(d);this.chartLabels.y2label=d}};DygraphCanvasRenderer.prototype._renderAnnotations=function(){var h={position:"absolute",fontSize:this.attr_("axisLabelFontSize")+"px",zIndex:10,overflow:"hidden"};var j=function(i,q,r,a){return function(s){var p=r.annotation;if(p.hasOwnProperty(i)){p[i](p,r,a.dygraph_,s)}else{if(a.dygraph_.attr_(q)){a.dygraph_.attr_(q)(p,r,a.dygraph_,s)}}}};var m=this.layout.annotated_points;for(var g=0;g<m.length;g++){var e=m[g];if(e.canvasx<this.area.x||e.canvasx>this.area.x+this.area.w){continue}var k=e.annotation;var l=6;if(k.hasOwnProperty("tickHeight")){l=k.tickHeight}var c=document.createElement("div");for(var b in h){if(h.hasOwnProperty(b)){c.style[b]=h[b]}}if(!k.hasOwnProperty("icon")){c.className="dygraphDefaultAnnotation"}if(k.hasOwnProperty("cssClass")){c.className+=" "+k.cssClass}var d=k.hasOwnProperty("width")?k.width:16;var n=k.hasOwnProperty("height")?k.height:16;if(k.hasOwnProperty("icon")){var f=document.createElement("img");f.src=k.icon;f.width=d;f.height=n;c.appendChild(f)}else{if(e.annotation.hasOwnProperty("shortText")){c.appendChild(document.createTextNode(e.annotation.shortText))}}c.style.left=(e.canvasx-d/2)+"px";if(k.attachAtBottom){c.style.top=(this.area.h-n-l)+"px"}else{c.style.top=(e.canvasy-n-l)+"px"}c.style.width=d+"px";c.style.height=n+"px";c.title=e.annotation.text;c.style.color=this.colors[e.name];c.style.borderColor=this.colors[e.name];k.div=c;Dygraph.addEvent(c,"click",j("clickHandler","annotationClickHandler",e,this));Dygraph.addEvent(c,"mouseover",j("mouseOverHandler","annotationMouseOverHandler",e,this));Dygraph.addEvent(c,"mouseout",j("mouseOutHandler","annotationMouseOutHandler",e,this));Dygraph.addEvent(c,"dblclick",j("dblClickHandler","annotationDblClickHandler",e,this));this.container.appendChild(c);this.annotations.push(c);var o=this.elementContext;o.strokeStyle=this.colors[e.name];o.beginPath();if(!k.attachAtBottom){o.moveTo(e.canvasx,e.canvasy);o.lineTo(e.canvasx,e.canvasy-2-l)}else{o.moveTo(e.canvasx,this.area.h);o.lineTo(e.canvasx,this.area.h-2-l)}o.closePath();o.stroke()}};DygraphCanvasRenderer.prototype._renderLineChart=function(){var F=function(i){return(i===null||isNaN(i))};var L=this.elementContext;var m=this.attr_("fillAlpha");var B=this.attr_("errorBars")||this.attr_("customBars");var k=this.attr_("fillGraph");var v=this.attr_("stackedGraph");var u=this.attr_("stepPlot");var z=this.layout.points;var y=z.length;var t,J,H,b,a,f,s,E,n,C,h,d,r;var D=[];for(var l in this.layout.datasets){if(this.layout.datasets.hasOwnProperty(l)){D.push(l)}}var w=D.length;this.colors={};for(J=0;J<w;J++){this.colors[D[J]]=this.colorScheme_[J%this.colorScheme_.length]}for(J=y;J--;){t=z[J];t.canvasx=this.area.w*t.x+this.area.x;t.canvasy=this.area.h*t.y+this.area.y}var q=L;if(B){if(k){this.dygraph_.warn("Can't use fillGraph option with error bars")}for(J=0;J<w;J++){E=D[J];r=this.dygraph_.axisPropertiesForSeries(E);s=this.colors[E];q.save();b=NaN;a=NaN;f=[-1,-1];d=r.yscale;h=new RGBColor(s);C="rgba("+h.r+","+h.g+","+h.b+","+m+")";q.fillStyle=C;q.beginPath();for(H=0;H<y;H++){t=z[H];if(t.name==E){if(!Dygraph.isOK(t.y)){b=NaN;continue}if(u){n=[t.y_bottom,t.y_top];a=t.y}else{n=[t.y_bottom,t.y_top]}n[0]=this.area.h*n[0]+this.area.y;n[1]=this.area.h*n[1]+this.area.y;if(!isNaN(b)){if(u){q.moveTo(b,n[0])}else{q.moveTo(b,f[0])}q.lineTo(t.canvasx,n[0]);q.lineTo(t.canvasx,n[1]);if(u){q.lineTo(b,n[1])}else{q.lineTo(b,f[1])}q.closePath()}f=n;b=t.canvasx}}q.fill()}}else{if(k){var G=[];for(J=w-1;J>=0;J--){E=D[J];s=this.colors[E];r=this.dygraph_.axisPropertiesForSeries(E);var e=1+r.minyval*r.yscale;if(e<0){e=0}else{if(e>1){e=1}}e=this.area.h*e+this.area.y;q.save();b=NaN;f=[-1,-1];d=r.yscale;h=new RGBColor(s);C="rgba("+h.r+","+h.g+","+h.b+","+m+")";q.fillStyle=C;q.beginPath();for(H=0;H<y;H++){t=z[H];if(t.name==E){if(!Dygraph.isOK(t.y)){b=NaN;continue}if(v){var g=G[t.canvasx];if(g===undefined){g=e}G[t.canvasx]=t.canvasy;n=[t.canvasy,g]}else{n=[t.canvasy,e]}if(!isNaN(b)){q.moveTo(b,f[0]);if(u){q.lineTo(t.canvasx,f[0])}else{q.lineTo(t.canvasx,n[0])}q.lineTo(t.canvasx,n[1]);q.lineTo(b,f[1]);q.closePath()}f=n;b=t.canvasx}}q.fill()}}}var K=0;var o=0;var c=0;for(J=0;J<w;J+=1){c=this.layout.setPointsLengths[J];o+=c;E=D[J];s=this.colors[E];var x=this.dygraph_.attr_("strokeWidth",E);L.save();var A=this.dygraph_.attr_("pointSize",E);b=null;a=null;var p=this.dygraph_.attr_("drawPoints",E);for(H=K;H<o;H++){t=z[H];if(F(t.canvasy)){if(u&&b!==null){q.beginPath();q.strokeStyle=s;q.lineWidth=this.attr_("strokeWidth");q.moveTo(b,a);q.lineTo(t.canvasx,a);q.stroke()}b=a=null}else{var I=(!b&&(H==z.length-1||F(z[H+1].canvasy)));if(b===null){b=t.canvasx;a=t.canvasy}else{if(Math.round(b)==Math.round(t.canvasx)&&Math.round(a)==Math.round(t.canvasy)){continue}if(x){q.beginPath();q.strokeStyle=s;q.lineWidth=x;q.moveTo(b,a);if(u){q.lineTo(t.canvasx,a)}b=t.canvasx;a=t.canvasy;q.lineTo(b,a);q.stroke()}}if(p||I){q.beginPath();q.fillStyle=s;q.arc(t.canvasx,t.canvasy,A,0,2*Math.PI,false);q.fill()}}}K=o}L.restore()};"use strict";var Dygraph=function(c,b,a){if(arguments.length>0){if(arguments.length==4){this.warn("Using deprecated four-argument dygraph constructor");this.__old_init__(c,b,arguments[2],arguments[3])}else{this.__init__(c,b,a)}}};Dygraph.NAME="Dygraph";Dygraph.VERSION="1.2";Dygraph.__repr__=function(){return"["+this.NAME+" "+this.VERSION+"]"};Dygraph.toString=function(){return this.__repr__()};Dygraph.DEFAULT_ROLL_PERIOD=1;Dygraph.DEFAULT_WIDTH=480;Dygraph.DEFAULT_HEIGHT=320;Dygraph.ANIMATION_STEPS=10;Dygraph.ANIMATION_DURATION=200;Dygraph.numberValueFormatter=function(a,e,h,d){var b=e("sigFigs");if(b!==null){return Dygraph.floatFormat(a,b)}var f=e("digitsAfterDecimal");var c=e("maxNumberWidth");if(a!==0&&(Math.abs(a)>=Math.pow(10,c)||Math.abs(a)<Math.pow(10,-f))){return a.toExponential(f)}else{return""+Dygraph.round_(a,f)}};Dygraph.numberAxisLabelFormatter=function(a,d,c,b){return Dygraph.numberValueFormatter(a,c,b)};Dygraph.dateString_=function(e){var i=Dygraph.zeropad;var h=new Date(e);var f=""+h.getFullYear();var g=i(h.getMonth()+1);var a=i(h.getDate());var c="";var b=h.getHours()*3600+h.getMinutes()*60+h.getSeconds();if(b){c=" "+Dygraph.hmsString_(e)}return f+"/"+g+"/"+a+c};Dygraph.dateAxisFormatter=function(b,c){if(c>=Dygraph.DECADAL){return b.strftime("%Y")}else{if(c>=Dygraph.MONTHLY){return b.strftime("%b %y")}else{var a=b.getHours()*3600+b.getMinutes()*60+b.getSeconds()+b.getMilliseconds();if(a===0||c>=Dygraph.DAILY){return new Date(b.getTime()+3600*1000).strftime("%d%b")}else{return Dygraph.hmsString_(b.getTime())}}}};Dygraph.DEFAULT_ATTRS={highlightCircleSize:3,labelsDivWidth:250,labelsDivStyles:{},labelsSeparateLines:false,labelsShowZeroValues:true,labelsKMB:false,labelsKMG2:false,showLabelsOnHighlight:true,digitsAfterDecimal:2,maxNumberWidth:6,sigFigs:null,strokeWidth:1,axisTickSize:3,axisLabelFontSize:14,xAxisLabelWidth:50,yAxisLabelWidth:50,rightGap:5,showRoller:false,xValueParser:Dygraph.dateParser,delimiter:",",sigma:2,errorBars:false,fractions:false,wilsonInterval:true,customBars:false,fillGraph:false,fillAlpha:0.15,connectSeparatedPoints:false,stackedGraph:false,hideOverlayOnMouseOut:true,legend:"onmouseover",stepPlot:false,avoidMinZero:false,titleHeight:28,xLabelHeight:18,yLabelWidth:18,drawXAxis:true,drawYAxis:true,axisLineColor:"black",axisLineWidth:0.3,gridLineWidth:0.3,axisLabelColor:"black",axisLabelFont:"Arial",axisLabelWidth:50,drawYGrid:true,drawXGrid:true,gridLineColor:"rgb(128,128,128)",interactionModel:null,animatedZooms:false,showRangeSelector:false,rangeSelectorHeight:40,rangeSelectorPlotStrokeColor:"#808FAB",rangeSelectorPlotFillColor:"#A7B1C4",axes:{x:{pixelsPerLabel:60,axisLabelFormatter:Dygraph.dateAxisFormatter,valueFormatter:Dygraph.dateString_,ticker:null},y:{pixelsPerLabel:30,valueFormatter:Dygraph.numberValueFormatter,axisLabelFormatter:Dygraph.numberAxisLabelFormatter,ticker:null},y2:{pixelsPerLabel:30,valueFormatter:Dygraph.numberValueFormatter,axisLabelFormatter:Dygraph.numberAxisLabelFormatter,ticker:null}}};Dygraph.HORIZONTAL=1;Dygraph.VERTICAL=2;Dygraph.addedAnnotationCSS=false;Dygraph.prototype.__old_init__=function(f,d,e,b){if(e!==null){var a=["Date"];for(var c=0;c<e.length;c++){a.push(e[c])}Dygraph.update(b,{labels:a})}this.__init__(f,d,b)};Dygraph.prototype.__init__=function(d,c,b){if(/MSIE/.test(navigator.userAgent)&&!window.opera&&typeof(G_vmlCanvasManager)!="undefined"&&document.readyState!="complete"){var a=this;setTimeout(function(){a.__init__(d,c,b)},100);return}if(b===null||b===undefined){b={}}b=Dygraph.mapLegacyOptions_(b);if(!d){Dygraph.error("Constructing dygraph with a non-existent div!");return}this.isUsingExcanvas_=typeof(G_vmlCanvasManager)!="undefined";this.maindiv_=d;this.file_=c;this.rollPeriod_=b.rollPeriod||Dygraph.DEFAULT_ROLL_PERIOD;this.previousVerticalX_=-1;this.fractions_=b.fractions||false;this.dateWindow_=b.dateWindow||null;this.is_initial_draw_=true;this.annotations_=[];this.zoomed_x_=false;this.zoomed_y_=false;d.innerHTML="";if(d.style.width===""&&b.width){d.style.width=b.width+"px"}if(d.style.height===""&&b.height){d.style.height=b.height+"px"}if(d.style.height===""&&d.clientHeight===0){d.style.height=Dygraph.DEFAULT_HEIGHT+"px";if(d.style.width===""){d.style.width=Dygraph.DEFAULT_WIDTH+"px"}}this.width_=d.clientWidth;this.height_=d.clientHeight;if(b.stackedGraph){b.fillGraph=true}this.user_attrs_={};Dygraph.update(this.user_attrs_,b);this.attrs_={};Dygraph.updateDeep(this.attrs_,Dygraph.DEFAULT_ATTRS);this.boundaryIds_=[];this.createInterface_();this.start_()};Dygraph.prototype.isZoomed=function(a){if(a==null){return this.zoomed_x_||this.zoomed_y_}if(a==="x"){return this.zoomed_x_}if(a==="y"){return this.zoomed_y_}throw"axis parameter is ["+a+"] must be null, 'x' or 'y'."};Dygraph.prototype.toString=function(){var a=this.maindiv_;var b=(a&&a.id)?a.id:a;return"[Dygraph "+b+"]"};Dygraph.prototype.attr_=function(b,a){if(a&&typeof(this.user_attrs_[a])!="undefined"&&this.user_attrs_[a]!==null&&typeof(this.user_attrs_[a][b])!="undefined"){return this.user_attrs_[a][b]}else{if(typeof(this.user_attrs_[b])!="undefined"){return this.user_attrs_[b]}else{if(typeof(this.attrs_[b])!="undefined"){return this.attrs_[b]}else{return null}}}};Dygraph.prototype.optionsViewForAxis_=function(b){var a=this;return function(c){var d=a.user_attrs_.axes;if(d&&d[b]&&d[b][c]){return d[b][c]}if(typeof(a.user_attrs_[c])!="undefined"){return a.user_attrs_[c]}d=a.attrs_.axes;if(d&&d[b]&&d[b][c]){return d[b][c]}if(b=="y"&&a.axes_[0].hasOwnProperty(c)){return a.axes_[0][c]}else{if(b=="y2"&&a.axes_[1].hasOwnProperty(c)){return a.axes_[1][c]}}return a.attr_(c)}};Dygraph.prototype.rollPeriod=function(){return this.rollPeriod_};Dygraph.prototype.xAxisRange=function(){return this.dateWindow_?this.dateWindow_:this.xAxisExtremes()};Dygraph.prototype.xAxisExtremes=function(){var b=this.rawData_[0][0];var a=this.rawData_[this.rawData_.length-1][0];return[b,a]};Dygraph.prototype.yAxisRange=function(a){if(typeof(a)=="undefined"){a=0}if(a<0||a>=this.axes_.length){return null}var b=this.axes_[a];return[b.computedValueRange[0],b.computedValueRange[1]]};Dygraph.prototype.yAxisRanges=function(){var a=[];for(var b=0;b<this.axes_.length;b++){a.push(this.yAxisRange(b))}return a};Dygraph.prototype.toDomCoords=function(a,c,b){return[this.toDomXCoord(a),this.toDomYCoord(c,b)]};Dygraph.prototype.toDomXCoord=function(b){if(b===null){return null}var c=this.plotter_.area;var a=this.xAxisRange();return c.x+(b-a[0])/(a[1]-a[0])*c.w};Dygraph.prototype.toDomYCoord=function(d,a){var c=this.toPercentYCoord(d,a);if(c===null){return null}var b=this.plotter_.area;return b.y+c*b.h};Dygraph.prototype.toDataCoords=function(a,c,b){return[this.toDataXCoord(a),this.toDataYCoord(c,b)]};Dygraph.prototype.toDataXCoord=function(b){if(b===null){return null}var c=this.plotter_.area;var a=this.xAxisRange();return a[0]+(b-c.x)/c.w*(a[1]-a[0])};Dygraph.prototype.toDataYCoord=function(h,b){if(h===null){return null}var c=this.plotter_.area;var g=this.yAxisRange(b);if(typeof(b)=="undefined"){b=0}if(!this.axes_[b].logscale){return g[0]+(c.y+c.h-h)/c.h*(g[1]-g[0])}else{var f=(h-c.y)/c.h;var a=Dygraph.log10(g[1]);var e=a-(f*(a-Dygraph.log10(g[0])));var d=Math.pow(Dygraph.LOG_SCALE,e);return d}};Dygraph.prototype.toPercentYCoord=function(e,b){if(e===null){return null}if(typeof(b)=="undefined"){b=0}var d=this.yAxisRange(b);var c;if(!this.axes_[b].logscale){c=(d[1]-e)/(d[1]-d[0])}else{var a=Dygraph.log10(d[1]);c=(a-Dygraph.log10(e))/(a-Dygraph.log10(d[0]))}return c};Dygraph.prototype.toPercentXCoord=function(b){if(b===null){return null}var a=this.xAxisRange();return(b-a[0])/(a[1]-a[0])};Dygraph.prototype.numColumns=function(){return this.rawData_[0]?this.rawData_[0].length:this.attr_("labels").length};Dygraph.prototype.numRows=function(){return this.rawData_.length};Dygraph.prototype.fullXRange_=function(){if(this.numRows()>0){return[this.rawData_[0][0],this.rawData_[this.numRows()-1][0]]}else{return[0,1]}};Dygraph.prototype.getValue=function(b,a){if(b<0||b>this.rawData_.length){return null}if(a<0||a>this.rawData_[b].length){return null}return this.rawData_[b][a]};Dygraph.prototype.createInterface_=function(){var a=this.maindiv_;this.graphDiv=document.createElement("div");this.graphDiv.style.width=this.width_+"px";this.graphDiv.style.height=this.height_+"px";a.appendChild(this.graphDiv);this.canvas_=Dygraph.createCanvas();this.canvas_.style.position="absolute";this.canvas_.width=this.width_;this.canvas_.height=this.height_;this.canvas_.style.width=this.width_+"px";this.canvas_.style.height=this.height_+"px";this.canvas_ctx_=Dygraph.getContext(this.canvas_);this.hidden_=this.createPlotKitCanvas_(this.canvas_);this.hidden_ctx_=Dygraph.getContext(this.hidden_);if(this.attr_("showRangeSelector")){this.rangeSelector_=new DygraphRangeSelector(this)}this.graphDiv.appendChild(this.hidden_);this.graphDiv.appendChild(this.canvas_);this.mouseEventElement_=this.createMouseEventElement_();this.layout_=new DygraphLayout(this);if(this.rangeSelector_){this.rangeSelector_.addToGraph(this.graphDiv,this.layout_)}var b=this;Dygraph.addEvent(this.mouseEventElement_,"mousemove",function(c){b.mouseMove_(c)});Dygraph.addEvent(this.mouseEventElement_,"mouseout",function(c){b.mouseOut_(c)});this.createStatusMessage_();this.createDragInterface_();Dygraph.addEvent(window,"resize",function(c){b.resize()})};Dygraph.prototype.destroy=function(){var a=function(c){while(c.hasChildNodes()){a(c.firstChild);c.removeChild(c.firstChild)}};a(this.maindiv_);var b=function(c){for(var d in c){if(typeof(c[d])==="object"){c[d]=null}}};b(this.layout_);b(this.plotter_);b(this)};Dygraph.prototype.createPlotKitCanvas_=function(a){var b=Dygraph.createCanvas();b.style.position="absolute";b.style.top=a.style.top;b.style.left=a.style.left;b.width=this.width_;b.height=this.height_;b.style.width=this.width_+"px";b.style.height=this.height_+"px";return b};Dygraph.prototype.createMouseEventElement_=function(){if(this.isUsingExcanvas_){var a=document.createElement("div");a.style.position="absolute";a.style.backgroundColor="white";a.style.filter="alpha(opacity=0)";a.style.width=this.width_+"px";a.style.height=this.height_+"px";this.graphDiv.appendChild(a);return a}else{return this.canvas_}};Dygraph.prototype.setColors_=function(){var e=this.attr_("labels").length-1;this.colors_=[];var a=this.attr_("colors");var d;if(!a){var c=this.attr_("colorSaturation")||1;var b=this.attr_("colorValue")||0.5;var j=Math.ceil(e/2);for(d=1;d<=e;d++){if(!this.visibility()[d-1]){continue}var g=d%2?Math.ceil(d/2):(j+d/2);var f=(1*g/(1+e));this.colors_.push(Dygraph.hsvToRGB(f,c,b))}}else{for(d=0;d<e;d++){if(!this.visibility()[d]){continue}var h=a[d%a.length];this.colors_.push(h)}}this.plotter_.setColors(this.colors_)};Dygraph.prototype.getColors=function(){return this.colors_};Dygraph.prototype.createStatusMessage_=function(){var d=this.user_attrs_.labelsDiv;if(d&&null!==d&&(typeof(d)=="string"||d instanceof String)){this.user_attrs_.labelsDiv=document.getElementById(d)}if(!this.attr_("labelsDiv")){var a=this.attr_("labelsDivWidth");var c={position:"absolute",fontSize:"14px",zIndex:10,width:a+"px",top:"0px",left:(this.width_-a-2)+"px",background:"white",textAlign:"left",overflow:"hidden"};Dygraph.update(c,this.attr_("labelsDivStyles"));var e=document.createElement("div");e.className="dygraph-legend";for(var b in c){if(c.hasOwnProperty(b)){e.style[b]=c[b]}}this.graphDiv.appendChild(e);this.attrs_.labelsDiv=e}};Dygraph.prototype.positionLabelsDiv_=function(){if(this.user_attrs_.hasOwnProperty("labelsDiv")){return}var a=this.plotter_.area;var b=this.attr_("labelsDiv");b.style.left=a.x+a.w-this.attr_("labelsDivWidth")-1+"px";b.style.top=a.y+"px"};Dygraph.prototype.createRollInterface_=function(){if(!this.roller_){this.roller_=document.createElement("input");this.roller_.type="text";this.roller_.style.display="none";this.graphDiv.appendChild(this.roller_)}var e=this.attr_("showRoller")?"block":"none";var d=this.plotter_.area;var b={position:"absolute",zIndex:10,top:(d.y+d.h-25)+"px",left:(d.x+1)+"px",display:e};this.roller_.size="2";this.roller_.value=this.rollPeriod_;for(var a in b){if(b.hasOwnProperty(a)){this.roller_.style[a]=b[a]}}var c=this;this.roller_.onchange=function(){c.adjustRoll(c.roller_.value)}};Dygraph.prototype.dragGetX_=function(b,a){return Dygraph.pageX(b)-a.px};Dygraph.prototype.dragGetY_=function(b,a){return Dygraph.pageY(b)-a.py};Dygraph.prototype.createDragInterface_=function(){var c={isZooming:false,isPanning:false,is2DPan:false,dragStartX:null,dragStartY:null,dragEndX:null,dragEndY:null,dragDirection:null,prevEndX:null,prevEndY:null,prevDragDirection:null,initialLeftmostDate:null,xUnitsPerPixel:null,dateRange:null,px:0,py:0,boundedDates:null,boundedValues:null,initializeMouseDown:function(i,h,f){if(i.preventDefault){i.preventDefault()}else{i.returnValue=false;i.cancelBubble=true}f.px=Dygraph.findPosX(h.canvas_);f.py=Dygraph.findPosY(h.canvas_);f.dragStartX=h.dragGetX_(i,f);f.dragStartY=h.dragGetY_(i,f)}};var e=this.attr_("interactionModel");var b=this;var d=function(f){return function(g){f(g,b,c)}};for(var a in e){if(!e.hasOwnProperty(a)){continue}Dygraph.addEvent(this.mouseEventElement_,a,d(e[a]))}Dygraph.addEvent(document,"mouseup",function(g){if(c.isZooming||c.isPanning){c.isZooming=false;c.dragStartX=null;c.dragStartY=null}if(c.isPanning){c.isPanning=false;c.draggingDate=null;c.dateRange=null;for(var f=0;f<b.axes_.length;f++){delete b.axes_[f].draggingValue;delete b.axes_[f].dragValueRange}}})};Dygraph.prototype.drawZoomRect_=function(e,c,i,b,g,a,f,d){var h=this.canvas_ctx_;if(a==Dygraph.HORIZONTAL){h.clearRect(Math.min(c,f),this.layout_.getPlotArea().y,Math.abs(c-f),this.layout_.getPlotArea().h)}else{if(a==Dygraph.VERTICAL){h.clearRect(this.layout_.getPlotArea().x,Math.min(b,d),this.layout_.getPlotArea().w,Math.abs(b-d))}}if(e==Dygraph.HORIZONTAL){if(i&&c){h.fillStyle="rgba(128,128,128,0.33)";h.fillRect(Math.min(c,i),this.layout_.getPlotArea().y,Math.abs(i-c),this.layout_.getPlotArea().h)}}else{if(e==Dygraph.VERTICAL){if(g&&b){h.fillStyle="rgba(128,128,128,0.33)";h.fillRect(this.layout_.getPlotArea().x,Math.min(b,g),this.layout_.getPlotArea().w,Math.abs(g-b))}}}if(this.isUsingExcanvas_){this.currentZoomRectArgs_=[e,c,i,b,g,0,0,0]}};Dygraph.prototype.clearZoomRect_=function(){this.currentZoomRectArgs_=null;this.canvas_ctx_.clearRect(0,0,this.canvas_.width,this.canvas_.height)};Dygraph.prototype.doZoomX_=function(c,a){this.currentZoomRectArgs_=null;var b=this.toDataXCoord(c);var d=this.toDataXCoord(a);this.doZoomXDates_(b,d)};Dygraph.zoomAnimationFunction=function(c,b){var a=1.5;return(1-Math.pow(a,-c))/(1-Math.pow(a,-b))};Dygraph.prototype.doZoomXDates_=function(c,e){var a=this.xAxisRange();var d=[c,e];this.zoomed_x_=true;var b=this;this.doAnimatedZoom(a,d,null,null,function(){if(b.attr_("zoomCallback")){b.attr_("zoomCallback")(c,e,b.yAxisRanges())}})};Dygraph.prototype.doZoomY_=function(h,f){this.currentZoomRectArgs_=null;var c=this.yAxisRanges();var b=[];for(var e=0;e<this.axes_.length;e++){var d=this.toDataYCoord(h,e);var a=this.toDataYCoord(f,e);b.push([a,d])}this.zoomed_y_=true;var g=this;this.doAnimatedZoom(null,null,c,b,function(){if(g.attr_("zoomCallback")){var i=g.xAxisRange();g.attr_("zoomCallback")(i[0],i[1],g.yAxisRanges())}})};Dygraph.prototype.doUnzoom_=function(){var c=false,d=false,a=false;if(this.dateWindow_!==null){c=true;d=true}for(var f=0;f<this.axes_.length;f++){if(this.axes_[f].valueWindow!==null){c=true;a=true}}this.clearSelection();if(c){this.zoomed_x_=false;this.zoomed_y_=false;var e=this.rawData_[0][0];var b=this.rawData_[this.rawData_.length-1][0];if(!this.attr_("animatedZooms")){this.dateWindow_=null;for(f=0;f<this.axes_.length;f++){if(this.axes_[f].valueWindow!==null){delete this.axes_[f].valueWindow}}this.drawGraph_();if(this.attr_("zoomCallback")){this.attr_("zoomCallback")(e,b,this.yAxisRanges())}return}var k=null,l=null,j=null,g=null;if(d){k=this.xAxisRange();l=[e,b]}if(a){j=this.yAxisRanges();var m=this.gatherDatasets_(this.rolledSeries_,null);var n=m[1];this.computeYAxisRanges_(n);g=[];for(f=0;f<this.axes_.length;f++){g.push(this.axes_[f].extremeRange)}}var h=this;this.doAnimatedZoom(k,l,j,g,function(){h.dateWindow_=null;for(var o=0;o<h.axes_.length;o++){if(h.axes_[o].valueWindow!==null){delete h.axes_[o].valueWindow}}if(h.attr_("zoomCallback")){h.attr_("zoomCallback")(e,b,h.yAxisRanges())}})}};Dygraph.prototype.doAnimatedZoom=function(a,e,b,c,m){var i=this.attr_("animatedZooms")?Dygraph.ANIMATION_STEPS:1;var l=[];var k=[];var f,d;if(a!==null&&e!==null){for(f=1;f<=i;f++){d=Dygraph.zoomAnimationFunction(f,i);l[f-1]=[a[0]*(1-d)+d*e[0],a[1]*(1-d)+d*e[1]]}}if(b!==null&&c!==null){for(f=1;f<=i;f++){d=Dygraph.zoomAnimationFunction(f,i);var n=[];for(var g=0;g<this.axes_.length;g++){n.push([b[g][0]*(1-d)+d*c[g][0],b[g][1]*(1-d)+d*c[g][1]])}k[f-1]=n}}var h=this;Dygraph.repeatAndCleanup(function(p){if(k.length){for(var o=0;o<h.axes_.length;o++){var j=k[p][o];h.axes_[o].valueWindow=[j[0],j[1]]}}if(l.length){h.dateWindow_=l[p]}h.drawGraph_()},i,Dygraph.ANIMATION_DURATION/i,m)};Dygraph.prototype.mouseMove_=function(b){var r=this.layout_.points;if(r===undefined){return}var a=Dygraph.pageX(b)-Dygraph.findPosX(this.mouseEventElement_);var j=-1;var f;var n=1e+100;var o=-1;for(f=0;f<r.length;f++){var q=r[f];if(q===null){continue}var h=Math.abs(q.canvasx-a);if(h>n){continue}n=h;o=f}if(o>=0){j=r[o].xval}this.selPoints_=[];var d=r.length;if(!this.attr_("stackedGraph")){for(f=0;f<d;f++){if(r[f].xval==j){this.selPoints_.push(r[f])}}}else{var g=0;for(f=d-1;f>=0;f--){if(r[f].xval==j){var c={};for(var e in r[f]){c[e]=r[f][e]}c.yval-=g;g+=c.yval;this.selPoints_.push(c)}}this.selPoints_.reverse()}if(this.attr_("highlightCallback")){var m=this.lastx_;if(m!==null&&j!=m){this.attr_("highlightCallback")(b,j,this.selPoints_,this.idxToRow_(o))}}this.lastx_=j;this.updateSelection_()};Dygraph.prototype.idxToRow_=function(a){if(a<0){return -1}for(var b in this.layout_.datasets){if(a<this.layout_.datasets[b].length){return this.boundaryIds_[0][0]+a}a-=this.layout_.datasets[b].length}return -1};Dygraph.prototype.generateLegendHTML_=function(o,p){var f,b,e,n;if(typeof(o)==="undefined"){if(this.attr_("legend")!="always"){return""}b=this.attr_("labelsSeparateLines");var h=this.attr_("labels");f="";for(e=1;e<h.length;e++){if(!this.visibility()[e-1]){continue}n=this.plotter_.colors[h[e]];if(f!==""){f+=(b?"<br/>":" ")}f+="<b><span style='color: "+n+";'>&mdash;"+h[e]+"</span></b>"}return f}var m=this.optionsViewForAxis_("x");var j=m("valueFormatter");f=j(o,m,this.attr_("labels")[0],this)+":";var d=[];var l=this.numAxes();for(e=0;e<l;e++){d[e]=this.optionsViewForAxis_("y"+(e?1+e:""))}var q=this.attr_("labelsShowZeroValues");b=this.attr_("labelsSeparateLines");for(e=0;e<this.selPoints_.length;e++){var r=this.selPoints_[e];if(r.yval===0&&!q){continue}if(!Dygraph.isOK(r.canvasy)){continue}if(b){f+="<br/>"}var g=d[this.seriesToAxisMap_[r.name]];var a=g("valueFormatter");n=this.plotter_.colors[r.name];var k=a(r.yval,g,r.name,this);f+=" <b><span style='color: "+n+";'>"+r.name+"</span></b>:"+k}return f};Dygraph.prototype.setLegendHTML_=function(a,d){var c=this.generateLegendHTML_(a,d);var b=this.attr_("labelsDiv");if(b!==null){b.innerHTML=c}else{if(typeof(this.shown_legend_error_)=="undefined"){this.error("labelsDiv is set to something nonexistent; legend will not be shown.");this.shown_legend_error_=true}}};Dygraph.prototype.updateSelection_=function(){var d;var h=this.canvas_ctx_;if(this.previousVerticalX_>=0){var e=0;var f=this.attr_("labels");for(d=1;d<f.length;d++){var b=this.attr_("highlightCircleSize",f[d]);if(b>e){e=b}}var g=this.previousVerticalX_;h.clearRect(g-e-1,0,2*e+2,this.height_)}if(this.isUsingExcanvas_&&this.currentZoomRectArgs_){Dygraph.prototype.drawZoomRect_.apply(this,this.currentZoomRectArgs_)}if(this.selPoints_.length>0){if(this.attr_("showLabelsOnHighlight")){this.setLegendHTML_(this.lastx_,this.selPoints_)}var c=this.selPoints_[0].canvasx;h.save();for(d=0;d<this.selPoints_.length;d++){var j=this.selPoints_[d];if(!Dygraph.isOK(j.canvasy)){continue}var a=this.attr_("highlightCircleSize",j.name);h.beginPath();h.fillStyle=this.plotter_.colors[j.name];h.arc(c,j.canvasy,a,0,2*Math.PI,false);h.fill()}h.restore();this.previousVerticalX_=c}};Dygraph.prototype.setSelection=function(c){this.selPoints_=[];var d=0;if(c!==false){c=c-this.boundaryIds_[0][0]}if(c!==false&&c>=0){for(var b in this.layout_.datasets){if(c<this.layout_.datasets[b].length){var a=this.layout_.points[d+c];if(this.attr_("stackedGraph")){a=this.layout_.unstackPointAtIndex(d+c)}this.selPoints_.push(a)}d+=this.layout_.datasets[b].length}}if(this.selPoints_.length){this.lastx_=this.selPoints_[0].xval;this.updateSelection_()}else{this.clearSelection()}};Dygraph.prototype.mouseOut_=function(a){if(this.attr_("unhighlightCallback")){this.attr_("unhighlightCallback")(a)}if(this.attr_("hideOverlayOnMouseOut")){this.clearSelection()}};Dygraph.prototype.clearSelection=function(){this.canvas_ctx_.clearRect(0,0,this.width_,this.height_);this.setLegendHTML_();this.selPoints_=[];this.lastx_=-1};Dygraph.prototype.getSelection=function(){if(!this.selPoints_||this.selPoints_.length<1){return -1}for(var a=0;a<this.layout_.points.length;a++){if(this.layout_.points[a].x==this.selPoints_[0].x){return a+this.boundaryIds_[0][0]}}return -1};Dygraph.prototype.loadedEvent_=function(a){this.rawData_=this.parseCSV_(a);this.predraw_()};Dygraph.prototype.addXTicks_=function(){var a;if(this.dateWindow_){a=[this.dateWindow_[0],this.dateWindow_[1]]}else{a=this.fullXRange_()}var c=this.optionsViewForAxis_("x");var b=c("ticker")(a[0],a[1],this.width_,c,this);this.layout_.setXTicks(b)};Dygraph.prototype.extremeValues_=function(d){var h=null,f=null,c,g;var b=this.attr_("errorBars")||this.attr_("customBars");if(b){for(c=0;c<d.length;c++){g=d[c][1][0];if(!g){continue}var a=g-d[c][1][1];var e=g+d[c][1][2];if(a>g){a=g}if(e<g){e=g}if(f===null||e>f){f=e}if(h===null||a<h){h=a}}}else{for(c=0;c<d.length;c++){g=d[c][1];if(g===null||isNaN(g)){continue}if(f===null||g>f){f=g}if(h===null||g<h){h=g}}}return[h,f]};Dygraph.prototype.predraw_=function(){var f=new Date();this.computeYAxes_();if(this.plotter_){this.plotter_.clear()}this.plotter_=new DygraphCanvasRenderer(this,this.hidden_,this.hidden_ctx_,this.layout_);this.createRollInterface_();this.positionLabelsDiv_();if(this.rangeSelector_){this.rangeSelector_.renderStaticLayer()}this.rolledSeries_=[null];for(var c=1;c<this.numColumns();c++){var e=this.attr_("connectSeparatedPoints",c);var d=this.attr_("logscale",c);var b=this.extractSeries_(this.rawData_,c,d,e);b=this.rollingAverage(b,this.rollPeriod_);this.rolledSeries_.push(b)}this.drawGraph_();var a=new Date();this.drawingTimeMs_=(a-f)};Dygraph.prototype.gatherDatasets_=function(w,c){var s=[];var b=[];var e=[];var a={};var u,t,r;var m=w.length-1;for(u=m;u>=1;u--){if(!this.visibility()[u-1]){continue}var h=[];for(t=0;t<w[u].length;t++){h.push(w[u][t])}var o=this.attr_("errorBars")||this.attr_("customBars");if(c){var A=c[0];var f=c[1];var p=[];var d=null,z=null;for(r=0;r<h.length;r++){if(h[r][0]>=A&&d===null){d=r}if(h[r][0]<=f){z=r}}if(d===null){d=0}if(d>0){d--}if(z===null){z=h.length-1}if(z<h.length-1){z++}s[u-1]=[d,z];for(r=d;r<=z;r++){p.push(h[r])}h=p}else{s[u-1]=[0,h.length-1]}var n=this.extremeValues_(h);if(o){for(t=0;t<h.length;t++){h[t]=[h[t][0],h[t][1][0],h[t][1][1],h[t][1][2]]}}else{if(this.attr_("stackedGraph")){var q=h.length;var y;for(t=0;t<q;t++){var g=h[t][0];if(b[g]===undefined){b[g]=0}y=h[t][1];b[g]+=y;h[t]=[g,b[g]];if(b[g]>n[1]){n[1]=b[g]}if(b[g]<n[0]){n[0]=b[g]}}}}var v=this.attr_("labels")[u];a[v]=n;e[u]=h}return[e,a,s]};Dygraph.prototype.drawGraph_=function(j){var a=new Date();if(typeof(j)==="undefined"){j=true}var e=this.is_initial_draw_;this.is_initial_draw_=false;this.layout_.removeAllDatasets();this.setColors_();this.attrs_.pointSize=0.5*this.attr_("highlightCircleSize");var g=this.gatherDatasets_(this.rolledSeries_,this.dateWindow_);var d=g[0];var h=g[1];this.boundaryIds_=g[2];for(var f=1;f<d.length;f++){if(!this.visibility()[f-1]){continue}this.layout_.addDataset(this.attr_("labels")[f],d[f])}this.computeYAxisRanges_(h);this.layout_.setYAxes(this.axes_);this.addXTicks_();var b=this.zoomed_x_;this.layout_.setDateWindow(this.dateWindow_);this.zoomed_x_=b;this.layout_.evaluateWithError();this.renderGraph_(e,false);if(this.attr_("timingName")){var c=new Date();if(console){console.log(this.attr_("timingName")+" - drawGraph: "+(c-a)+"ms")}}};Dygraph.prototype.renderGraph_=function(a,b){this.plotter_.clear();this.plotter_.render();this.canvas_.getContext("2d").clearRect(0,0,this.canvas_.width,this.canvas_.height);this.setLegendHTML_();if(!a){if(b){if(typeof(this.selPoints_)!=="undefined"&&this.selPoints_.length){this.clearSelection()}else{this.clearSelection()}}}if(this.rangeSelector_){this.rangeSelector_.renderInteractiveLayer()}if(this.attr_("drawCallback")!==null){this.attr_("drawCallback")(this,a)}};Dygraph.prototype.computeYAxes_=function(){var g,c,m,b,j,a,p;if(this.axes_!==undefined&&this.user_attrs_.hasOwnProperty("valueRange")===false){c=[];for(j=0;j<this.axes_.length;j++){c.push(this.axes_[j].valueWindow)}}this.axes_=[{yAxisId:0,g:this}];this.seriesToAxisMap_={};var h=this.attr_("labels");var f={};for(g=1;g<h.length;g++){f[h[g]]=(g-1)}var e=["includeZero","valueRange","labelsKMB","labelsKMG2","pixelsPerYLabel","yAxisLabelWidth","axisLabelFontSize","axisTickSize","logscale"];for(g=0;g<e.length;g++){var d=e[g];p=this.attr_(d);if(p){this.axes_[0][d]=p}}for(m in f){if(!f.hasOwnProperty(m)){continue}b=this.attr_("axis",m);if(b===null){this.seriesToAxisMap_[m]=0;continue}if(typeof(b)=="object"){a={};Dygraph.update(a,this.axes_[0]);Dygraph.update(a,{valueRange:null});var o=this.axes_.length;a.yAxisId=o;a.g=this;Dygraph.update(a,b);this.axes_.push(a);this.seriesToAxisMap_[m]=o}}for(m in f){if(!f.hasOwnProperty(m)){continue}b=this.attr_("axis",m);if(typeof(b)=="string"){if(!this.seriesToAxisMap_.hasOwnProperty(b)){this.error("Series "+m+" wants to share a y-axis with series "+b+", which does not define its own axis.");return null}var n=this.seriesToAxisMap_[b];this.seriesToAxisMap_[m]=n}}if(c!==undefined){for(j=0;j<c.length;j++){this.axes_[j].valueWindow=c[j]}}for(b=0;b<this.axes_.length;b++){if(b===0){a=this.optionsViewForAxis_("y"+(b?"2":""));p=a("valueRange");if(p){this.axes_[b].valueRange=p}}else{var l=this.user_attrs_.axes;if(l&&l.y2){p=l.y2.valueRange;if(p){this.axes_[b].valueRange=p}}}}};Dygraph.prototype.numAxes=function(){var c=0;for(var b in this.seriesToAxisMap_){if(!this.seriesToAxisMap_.hasOwnProperty(b)){continue}var a=this.seriesToAxisMap_[b];if(a>c){c=a}}return 1+c};Dygraph.prototype.axisPropertiesForSeries=function(a){return this.axes_[this.seriesToAxisMap_[a]]};Dygraph.prototype.computeYAxisRanges_=function(a){var g=[],h;for(h in this.seriesToAxisMap_){if(!this.seriesToAxisMap_.hasOwnProperty(h)){continue}var p=this.seriesToAxisMap_[h];while(g.length<=p){g.push([])}g[p].push(h)}for(var u=0;u<this.axes_.length;u++){var b=this.axes_[u];if(!g[u]){b.extremeRange=[0,1]}else{h=g[u];var x=Infinity;var w=-Infinity;var o,m;for(var s=0;s<h.length;s++){if(!a.hasOwnProperty(h[s])){continue}o=a[h[s]][0];if(o!==null){x=Math.min(o,x)}m=a[h[s]][1];if(m!==null){w=Math.max(m,w)}}if(b.includeZero&&x>0){x=0}if(x==Infinity){x=0}if(w==-Infinity){w=1}var t=w-x;if(t===0){t=w}var d,z;if(b.logscale){d=w+0.1*t;z=x}else{d=w+0.1*t;z=x-0.1*t;if(!this.attr_("avoidMinZero")){if(z<0&&x>=0){z=0}if(d>0&&w<=0){d=0}}if(this.attr_("includeZero")){if(w<0){d=0}if(x>0){z=0}}}b.extremeRange=[z,d]}if(b.valueWindow){b.computedValueRange=[b.valueWindow[0],b.valueWindow[1]]}else{if(b.valueRange){b.computedValueRange=[b.valueRange[0],b.valueRange[1]]}else{b.computedValueRange=b.extremeRange}}var n=this.optionsViewForAxis_("y"+(u?"2":""));var y=n("ticker");if(u===0||b.independentTicks){b.ticks=y(b.computedValueRange[0],b.computedValueRange[1],this.height_,n,this)}else{var l=this.axes_[0];var e=l.ticks;var f=l.computedValueRange[1]-l.computedValueRange[0];var A=b.computedValueRange[1]-b.computedValueRange[0];var c=[];for(var r=0;r<e.length;r++){var q=(e[r].v-l.computedValueRange[0])/f;var v=b.computedValueRange[0]+q*A;c.push(v)}b.ticks=y(b.computedValueRange[0],b.computedValueRange[1],this.height_,n,this,c)}}};Dygraph.prototype.extractSeries_=function(h,e,g,f){var d=[];for(var c=0;c<h.length;c++){var b=h[c][0];var a=h[c][e];if(g){if(a<=0){a=null}d.push([b,a])}else{if(a!==null||!f){d.push([b,a])}}}return d};Dygraph.prototype.rollingAverage=function(l,d){if(l.length<2){return l}d=Math.min(d,l.length);var b=[];var s=this.attr_("sigma");var E,o,w,v,m,c,D,x;if(this.fractions_){var k=0;var h=0;var e=100;for(w=0;w<l.length;w++){k+=l[w][1][0];h+=l[w][1][1];if(w-d>=0){k-=l[w-d][1][0];h-=l[w-d][1][1]}var A=l[w][0];var u=h?k/h:0;if(this.attr_("errorBars")){if(this.attr_("wilsonInterval")){if(h){var r=u<0?0:u,t=h;var z=s*Math.sqrt(r*(1-r)/t+s*s/(4*t*t));var a=1+s*s/h;E=(r+s*s/(2*h)-z)/a;o=(r+s*s/(2*h)+z)/a;b[w]=[A,[r*e,(r-E)*e,(o-r)*e]]}else{b[w]=[A,[0,0,0]]}}else{x=h?s*Math.sqrt(u*(1-u)/h):1;b[w]=[A,[e*u,e*x,e*x]]}}else{b[w]=[A,e*u]}}}else{if(this.attr_("customBars")){E=0;var B=0;o=0;var g=0;for(w=0;w<l.length;w++){var C=l[w][1];m=C[1];b[w]=[l[w][0],[m,m-C[0],C[2]-m]];if(m!==null&&!isNaN(m)){E+=C[0];B+=m;o+=C[2];g+=1}if(w-d>=0){var q=l[w-d];if(q[1][1]!==null&&!isNaN(q[1][1])){E-=q[1][0];B-=q[1][1];o-=q[1][2];g-=1}}if(g){b[w]=[l[w][0],[1*B/g,1*(B-E)/g,1*(o-B)/g]]}else{b[w]=[l[w][0],[null,null,null]]}}}else{if(!this.attr_("errorBars")){if(d==1){return l}for(w=0;w<l.length;w++){c=0;D=0;for(v=Math.max(0,w-d+1);v<w+1;v++){m=l[v][1];if(m===null||isNaN(m)){continue}D++;c+=l[v][1]}if(D){b[w]=[l[w][0],c/D]}else{b[w]=[l[w][0],null]}}}else{for(w=0;w<l.length;w++){c=0;var f=0;D=0;for(v=Math.max(0,w-d+1);v<w+1;v++){m=l[v][1][0];if(m===null||isNaN(m)){continue}D++;c+=l[v][1][0];f+=Math.pow(l[v][1][1],2)}if(D){x=Math.sqrt(f)/D;b[w]=[l[w][0],[c/D,s*x,s*x]]}else{b[w]=[l[w][0],[null,null,null]]}}}}}return b};Dygraph.prototype.detectTypeFromString_=function(b){var a=false;var c=b.indexOf("-");if((c>0&&(b[c-1]!="e"&&b[c-1]!="E"))||b.indexOf("/")>=0||isNaN(parseFloat(b))){a=true}else{if(b.length==8&&b>"19700101"&&b<"20371231"){a=true}}if(a){this.attrs_.xValueParser=Dygraph.dateParser;this.attrs_.axes.x.valueFormatter=Dygraph.dateString_;this.attrs_.axes.x.ticker=Dygraph.dateTicker;this.attrs_.axes.x.axisLabelFormatter=Dygraph.dateAxisFormatter}else{this.attrs_.xValueParser=function(d){return parseFloat(d)};this.attrs_.axes.x.valueFormatter=function(d){return d};this.attrs_.axes.x.ticker=Dygraph.numericTicks;this.attrs_.axes.x.axisLabelFormatter=this.attrs_.axes.x.valueFormatter}};Dygraph.prototype.parseFloat_=function(a,c,b){var e=parseFloat(a);if(!isNaN(e)){return e}if(/^ *$/.test(a)){return null}if(/^ *nan *$/i.test(a)){return NaN}var d="Unable to parse '"+a+"' as a number";if(b!==null&&c!==null){d+=" on line "+(1+c)+" ('"+b+"') of CSV."}this.error(d);return null};Dygraph.prototype.parseCSV_=function(s){var r=[];var a=s.split("\n");var g,k;var p=this.attr_("delimiter");if(a[0].indexOf(p)==-1&&a[0].indexOf("\t")>=0){p="\t"}var b=0;if(!("labels" in this.user_attrs_)){b=1;this.attrs_.labels=a[0].split(p)}var o=0;var m;var q=false;var c=this.attr_("labels").length;var f=false;for(var l=b;l<a.length;l++){var e=a[l];o=l;if(e.length===0){continue}if(e[0]=="#"){continue}var d=e.split(p);if(d.length<2){continue}var h=[];if(!q){this.detectTypeFromString_(d[0]);m=this.attr_("xValueParser");q=true}h[0]=m(d[0],this);if(this.fractions_){for(k=1;k<d.length;k++){g=d[k].split("/");if(g.length!=2){this.error('Expected fractional "num/den" values in CSV data but found a value \''+d[k]+"' on line "+(1+l)+" ('"+e+"') which is not of this form.");h[k]=[0,0]}else{h[k]=[this.parseFloat_(g[0],l,e),this.parseFloat_(g[1],l,e)]}}}else{if(this.attr_("errorBars")){if(d.length%2!=1){this.error("Expected alternating (value, stdev.) pairs in CSV data but line "+(1+l)+" has an odd number of values ("+(d.length-1)+"): '"+e+"'")}for(k=1;k<d.length;k+=2){h[(k+1)/2]=[this.parseFloat_(d[k],l,e),this.parseFloat_(d[k+1],l,e)]}}else{if(this.attr_("customBars")){for(k=1;k<d.length;k++){var t=d[k];if(/^ *$/.test(t)){h[k]=[null,null,null]}else{g=t.split(";");if(g.length==3){h[k]=[this.parseFloat_(g[0],l,e),this.parseFloat_(g[1],l,e),this.parseFloat_(g[2],l,e)]}else{this.warn('When using customBars, values must be either blank or "low;center;high" tuples (got "'+t+'" on line '+(1+l))}}}}else{for(k=1;k<d.length;k++){h[k]=this.parseFloat_(d[k],l,e)}}}}if(r.length>0&&h[0]<r[r.length-1][0]){f=true}if(h.length!=c){this.error("Number of columns in line "+l+" ("+h.length+") does not agree with number of labels ("+c+") "+e)}if(l===0&&this.attr_("labels")){var n=true;for(k=0;n&&k<h.length;k++){if(h[k]){n=false}}if(n){this.warn("The dygraphs 'labels' option is set, but the first row of CSV data ('"+e+"') appears to also contain labels. Will drop the CSV labels and use the option labels.");continue}}r.push(h)}if(f){this.warn("CSV is out of order; order it correctly to speed loading.");r.sort(function(j,i){return j[0]-i[0]})}return r};Dygraph.prototype.parseArray_=function(b){if(b.length===0){this.error("Can't plot empty data set");return null}if(b[0].length===0){this.error("Data set cannot contain an empty row");return null}var a;if(this.attr_("labels")===null){this.warn("Using default labels. Set labels explicitly via 'labels' in the options parameter");this.attrs_.labels=["X"];for(a=1;a<b[0].length;a++){this.attrs_.labels.push("Y"+a)}}if(Dygraph.isDateLike(b[0][0])){this.attrs_.axes.x.valueFormatter=Dygraph.dateString_;this.attrs_.axes.x.axisLabelFormatter=Dygraph.dateAxisFormatter;this.attrs_.axes.x.ticker=Dygraph.dateTicker;var c=Dygraph.clone(b);for(a=0;a<b.length;a++){if(c[a].length===0){this.error("Row "+(1+a)+" of data is empty");return null}if(c[a][0]===null||typeof(c[a][0].getTime)!="function"||isNaN(c[a][0].getTime())){this.error("x value in row "+(1+a)+" is not a Date");return null}c[a][0]=c[a][0].getTime()}return c}else{this.attrs_.axes.x.valueFormatter=function(d){return d};this.attrs_.axes.x.axisLabelFormatter=Dygraph.numberAxisLabelFormatter;this.attrs_.axes.x.ticker=Dygraph.numericTicks;return b}};Dygraph.prototype.parseDataTable_=function(v){var g=v.getNumberOfColumns();var f=v.getNumberOfRows();var e=v.getColumnType(0);if(e=="date"||e=="datetime"){this.attrs_.xValueParser=Dygraph.dateParser;this.attrs_.axes.x.valueFormatter=Dygraph.dateString_;this.attrs_.axes.x.ticker=Dygraph.dateTicker;this.attrs_.axes.x.axisLabelFormatter=Dygraph.dateAxisFormatter}else{if(e=="number"){this.attrs_.xValueParser=function(i){return parseFloat(i)};this.attrs_.axes.x.valueFormatter=function(i){return i};this.attrs_.axes.x.ticker=Dygraph.numericTicks;this.attrs_.axes.x.axisLabelFormatter=this.attrs_.axes.x.valueFormatter}else{this.error("only 'date', 'datetime' and 'number' types are supported for column 1 of DataTable input (Got '"+e+"')");return null}}var l=[];var s={};var r=false;var p,n;for(p=1;p<g;p++){var b=v.getColumnType(p);if(b=="number"){l.push(p)}else{if(b=="string"&&this.attr_("displayAnnotations")){var q=l[l.length-1];if(!s.hasOwnProperty(q)){s[q]=[p]}else{s[q].push(p)}r=true}else{this.error("Only 'number' is supported as a dependent type with Gviz. 'string' is only supported if displayAnnotations is true")}}}var t=[v.getColumnLabel(0)];for(p=0;p<l.length;p++){t.push(v.getColumnLabel(l[p]));if(this.attr_("errorBars")){p+=1}}this.attrs_.labels=t;g=t.length;var u=[];var h=false;var a=[];for(p=0;p<f;p++){var d=[];if(typeof(v.getValue(p,0))==="undefined"||v.getValue(p,0)===null){this.warn("Ignoring row "+p+" of DataTable because of undefined or null first column.");continue}if(e=="date"||e=="datetime"){d.push(v.getValue(p,0).getTime())}else{d.push(v.getValue(p,0))}if(!this.attr_("errorBars")){for(n=0;n<l.length;n++){var c=l[n];d.push(v.getValue(p,c));if(r&&s.hasOwnProperty(c)&&v.getValue(p,s[c][0])!==null){var o={};o.series=v.getColumnLabel(c);o.xval=d[0];o.shortText=String.fromCharCode(65+a.length);o.text="";for(var m=0;m<s[c].length;m++){if(m){o.text+="\n"}o.text+=v.getValue(p,s[c][m])}a.push(o)}}for(n=0;n<d.length;n++){if(!isFinite(d[n])){d[n]=null}}}else{for(n=0;n<g-1;n++){d.push([v.getValue(p,1+2*n),v.getValue(p,2+2*n)])}}if(u.length>0&&d[0]<u[u.length-1][0]){h=true}u.push(d)}if(h){this.warn("DataTable is out of order; order it correctly to speed loading.");u.sort(function(j,i){return j[0]-i[0]})}this.rawData_=u;if(a.length>0){this.setAnnotations(a,true)}};Dygraph.prototype.start_=function(){var c=this.file_;if(typeof c=="function"){c=c()}if(Dygraph.isArrayLike(c)){this.rawData_=this.parseArray_(c);this.predraw_()}else{if(typeof c=="object"&&typeof c.getColumnRange=="function"){this.parseDataTable_(c);this.predraw_()}else{if(typeof c=="string"){if(c.indexOf("\n")>=0){this.loadedEvent_(c)}else{var b=new XMLHttpRequest();var a=this;b.onreadystatechange=function(){if(b.readyState==4){if(b.status===200||b.status===0){a.loadedEvent_(b.responseText)}}};b.open("GET",c,true);b.send(null)}}else{this.error("Unknown data format: "+(typeof c))}}}};Dygraph.prototype.updateOptions=function(e,b){if(typeof(b)=="undefined"){b=false}var d=e.file;var c=Dygraph.mapLegacyOptions_(e);if("rollPeriod" in c){this.rollPeriod_=c.rollPeriod}if("dateWindow" in c){this.dateWindow_=c.dateWindow;if(!("isZoomedIgnoreProgrammaticZoom" in c)){this.zoomed_x_=(c.dateWindow!==null)}}if("valueRange" in c&&!("isZoomedIgnoreProgrammaticZoom" in c)){this.zoomed_y_=(c.valueRange!==null)}var a=Dygraph.isPixelChangingOptionList(this.attr_("labels"),c);Dygraph.updateDeep(this.user_attrs_,c);if(d){this.file_=d;if(!b){this.start_()}}else{if(!b){if(a){this.predraw_()}else{this.renderGraph_(false,false)}}}};Dygraph.mapLegacyOptions_=function(c){var a={};for(var b in c){if(b=="file"){continue}if(c.hasOwnProperty(b)){a[b]=c[b]}}var e=function(g,f,h){if(!a.axes){a.axes={}}if(!a.axes[g]){a.axes[g]={}}a.axes[g][f]=h};var d=function(f,g,h){if(typeof(c[f])!="undefined"){e(g,h,c[f]);delete a[f]}};d("xValueFormatter","x","valueFormatter");d("pixelsPerXLabel","x","pixelsPerLabel");d("xAxisLabelFormatter","x","axisLabelFormatter");d("xTicker","x","ticker");d("yValueFormatter","y","valueFormatter");d("pixelsPerYLabel","y","pixelsPerLabel");d("yAxisLabelFormatter","y","axisLabelFormatter");d("yTicker","y","ticker");return a};Dygraph.prototype.resize=function(d,b){if(this.resize_lock){return}this.resize_lock=true;if((d===null)!=(b===null)){this.warn("Dygraph.resize() should be called with zero parameters or two non-NULL parameters. Pretending it was zero.");d=b=null}var a=this.width_;var c=this.height_;if(d){this.maindiv_.style.width=d+"px";this.maindiv_.style.height=b+"px";this.width_=d;this.height_=b}else{this.width_=this.maindiv_.clientWidth;this.height_=this.maindiv_.clientHeight}if(a!=this.width_||c!=this.height_){this.maindiv_.innerHTML="";this.roller_=null;this.attrs_.labelsDiv=null;this.createInterface_();if(this.annotations_.length){this.layout_.setAnnotations(this.annotations_)}this.predraw_()}this.resize_lock=false};Dygraph.prototype.adjustRoll=function(a){this.rollPeriod_=a;this.predraw_()};Dygraph.prototype.visibility=function(){if(!this.attr_("visibility")){this.attrs_.visibility=[]}while(this.attr_("visibility").length<this.numColumns()-1){this.attrs_.visibility.push(true)}return this.attr_("visibility")};Dygraph.prototype.setVisibility=function(b,c){var a=this.visibility();if(b<0||b>=a.length){this.warn("invalid series number in setVisibility: "+b)}else{a[b]=c;this.predraw_()}};Dygraph.prototype.size=function(){return{width:this.width_,height:this.height_}};Dygraph.prototype.setAnnotations=function(b,a){Dygraph.addAnnotationRule();this.annotations_=b;this.layout_.setAnnotations(this.annotations_);if(!a){this.predraw_()}};Dygraph.prototype.annotations=function(){return this.annotations_};Dygraph.prototype.indexFromSetName=function(a){var c=this.attr_("labels");for(var b=0;b<c.length;b++){if(c[b]==a){return b}}return null};Dygraph.addAnnotationRule=function(){if(Dygraph.addedAnnotationCSS){return}var f="border: 1px solid black; background-color: white; text-align: center;";var e=document.createElement("style");e.type="text/css";document.getElementsByTagName("head")[0].appendChild(e);for(var b=0;b<document.styleSheets.length;b++){if(document.styleSheets[b].disabled){continue}var d=document.styleSheets[b];try{if(d.insertRule){var a=d.cssRules?d.cssRules.length:0;d.insertRule(".dygraphDefaultAnnotation { "+f+" }",a)}else{if(d.addRule){d.addRule(".dygraphDefaultAnnotation",f)}}Dygraph.addedAnnotationCSS=true;return}catch(c){}}this.warn("Unable to add default annotation CSS rule; display may be off.")};var DateGraph=Dygraph;"use strict";Dygraph.LOG_SCALE=10;Dygraph.LN_TEN=Math.log(Dygraph.LOG_SCALE);Dygraph.log10=function(a){return Math.log(a)/Dygraph.LN_TEN};Dygraph.DEBUG=1;Dygraph.INFO=2;Dygraph.WARNING=3;Dygraph.ERROR=3;Dygraph.LOG_STACK_TRACES=false;Dygraph.log=function(b,d){var a;if(typeof(printStackTrace)!="undefined"){a=printStackTrace({guess:false});while(a[0].indexOf("stacktrace")!=-1){a.splice(0,1)}a.splice(0,2);for(var c=0;c<a.length;c++){a[c]=a[c].replace(/\([^)]*\/(.*)\)/,"@$1").replace(/\@.*\/([^\/]*)/,"@$1").replace("[object Object].","")}var e=a.splice(0,1)[0];d+=" ("+e.replace(/^.*@ ?/,"")+")"}if(typeof(console)!="undefined"){switch(b){case Dygraph.DEBUG:console.debug("dygraphs: "+d);break;case Dygraph.INFO:console.info("dygraphs: "+d);break;case Dygraph.WARNING:console.warn("dygraphs: "+d);break;case Dygraph.ERROR:console.error("dygraphs: "+d);break}}if(Dygraph.LOG_STACK_TRACES){console.log(a.join("\n"))}};Dygraph.info=function(a){Dygraph.log(Dygraph.INFO,a)};Dygraph.prototype.info=Dygraph.info;Dygraph.warn=function(a){Dygraph.log(Dygraph.WARNING,a)};Dygraph.prototype.warn=Dygraph.warn;Dygraph.error=function(a){Dygraph.log(Dygraph.ERROR,a)};Dygraph.prototype.error=Dygraph.error;Dygraph.getContext=function(a){return a.getContext("2d")};Dygraph.addEvent=function addEvent(c,b,a){if(c.addEventListener){c.addEventListener(b,a,false)}else{c[b+a]=function(){a(window.event)};c.attachEvent("on"+b,c[b+a])}};Dygraph.removeEvent=function addEvent(c,b,a){if(c.removeEventListener){c.removeEventListener(b,a,false)}else{c.detachEvent("on"+b,c[b+a]);c[b+a]=null}};Dygraph.cancelEvent=function(a){a=a?a:window.event;if(a.stopPropagation){a.stopPropagation()}if(a.preventDefault){a.preventDefault()}a.cancelBubble=true;a.cancel=true;a.returnValue=false;return false};Dygraph.hsvToRGB=function(h,g,k){var c;var d;var l;if(g===0){c=k;d=k;l=k}else{var e=Math.floor(h*6);var j=(h*6)-e;var b=k*(1-g);var a=k*(1-(g*j));var m=k*(1-(g*(1-j)));switch(e){case 1:c=a;d=k;l=b;break;case 2:c=b;d=k;l=m;break;case 3:c=b;d=a;l=k;break;case 4:c=m;d=b;l=k;break;case 5:c=k;d=b;l=a;break;case 6:case 0:c=k;d=m;l=b;break}}c=Math.floor(255*c+0.5);d=Math.floor(255*d+0.5);l=Math.floor(255*l+0.5);return"rgb("+c+","+d+","+l+")"};Dygraph.findPosX=function(b){var c=0;if(b.offsetParent){var a=b;while(1){c+=a.offsetLeft;if(!a.offsetParent){break}a=a.offsetParent}}else{if(b.x){c+=b.x}}while(b&&b!=document.body){c-=b.scrollLeft;b=b.parentNode}return c};Dygraph.findPosY=function(c){var b=0;if(c.offsetParent){var a=c;while(1){b+=a.offsetTop;if(!a.offsetParent){break}a=a.offsetParent}}else{if(c.y){b+=c.y}}while(c&&c!=document.body){b-=c.scrollTop;c=c.parentNode}return b};Dygraph.pageX=function(c){if(c.pageX){return(!c.pageX||c.pageX<0)?0:c.pageX}else{var d=document;var a=document.body;return c.clientX+(d.scrollLeft||a.scrollLeft)-(d.clientLeft||0)}};Dygraph.pageY=function(c){if(c.pageY){return(!c.pageY||c.pageY<0)?0:c.pageY}else{var d=document;var a=document.body;return c.clientY+(d.scrollTop||a.scrollTop)-(d.clientTop||0)}};Dygraph.isOK=function(a){return a&&!isNaN(a)};Dygraph.floatFormat=function(a,b){var c=Math.min(Math.max(1,b||2),21);return(Math.abs(a)<0.001&&a!==0)?a.toExponential(c-1):a.toPrecision(c)};Dygraph.zeropad=function(a){if(a<10){return"0"+a}else{return""+a}};Dygraph.hmsString_=function(a){var c=Dygraph.zeropad;var b=new Date(a);if(b.getSeconds()){return c(b.getHours())+":"+c(b.getMinutes())+":"+c(b.getSeconds())}else{return c(b.getHours())+":"+c(b.getMinutes())}};Dygraph.round_=function(c,b){var a=Math.pow(10,b);return Math.round(c*a)/a};Dygraph.binarySearch=function(a,d,i,e,b){if(e===null||e===undefined||b===null||b===undefined){e=0;b=d.length-1}if(e>b){return -1}if(i===null||i===undefined){i=0}var h=function(j){return j>=0&&j<d.length};var g=parseInt((e+b)/2,10);var c=d[g];if(c==a){return g}var f;if(c>a){if(i>0){f=g-1;if(h(f)&&d[f]<a){return g}}return Dygraph.binarySearch(a,d,i,e,g-1)}if(c<a){if(i<0){f=g+1;if(h(f)&&d[f]>a){return g}}return Dygraph.binarySearch(a,d,i,g+1,b)}};Dygraph.dateParser=function(a){var b;var c;c=Dygraph.dateStrToMillis(a);if(c&&!isNaN(c)){return c}if(a.search("-")!=-1){b=a.replace("-","/","g");while(b.search("-")!=-1){b=b.replace("-","/")}c=Dygraph.dateStrToMillis(b)}else{if(a.length==8){b=a.substr(0,4)+"/"+a.substr(4,2)+"/"+a.substr(6,2);c=Dygraph.dateStrToMillis(b)}else{c=Dygraph.dateStrToMillis(a)}}if(!c||isNaN(c)){Dygraph.error("Couldn't parse "+a+" as a date")}return c};Dygraph.dateStrToMillis=function(a){return new Date(a).getTime()};Dygraph.update=function(b,c){if(typeof(c)!="undefined"&&c!==null){for(var a in c){if(c.hasOwnProperty(a)){b[a]=c[a]}}}return b};Dygraph.updateDeep=function(b,d){function c(e){return(typeof Node==="object"?e instanceof Node:typeof e==="object"&&typeof e.nodeType==="number"&&typeof e.nodeName==="string")}if(typeof(d)!="undefined"&&d!==null){for(var a in d){if(d.hasOwnProperty(a)){if(d[a]===null){b[a]=null}else{if(Dygraph.isArrayLike(d[a])){b[a]=d[a].slice()}else{if(c(d[a])){b[a]=d[a]}else{if(typeof(d[a])=="object"){if(typeof(b[a])!="object"){b[a]={}}Dygraph.updateDeep(b[a],d[a])}else{b[a]=d[a]}}}}}}}return b};Dygraph.isArrayLike=function(b){var a=typeof(b);if((a!="object"&&!(a=="function"&&typeof(b.item)=="function"))||b===null||typeof(b.length)!="number"||b.nodeType===3){return false}return true};Dygraph.isDateLike=function(a){if(typeof(a)!="object"||a===null||typeof(a.getTime)!="function"){return false}return true};Dygraph.clone=function(c){var b=[];for(var a=0;a<c.length;a++){if(Dygraph.isArrayLike(c[a])){b.push(Dygraph.clone(c[a]))}else{b.push(c[a])}}return b};Dygraph.createCanvas=function(){var a=document.createElement("canvas");var b=(/MSIE/.test(navigator.userAgent)&&!window.opera);if(b&&(typeof(G_vmlCanvasManager)!="undefined")){a=G_vmlCanvasManager.initElement(a)}return a};Dygraph.isAndroid=function(){return(/Android/).test(navigator.userAgent)};Dygraph.repeatAndCleanup=function(b,g,f,c){var e=0;var d=new Date().getTime();b(e);if(g==1){c();return}(function a(){if(e>=g){return}var h=d+(1+e)*f;setTimeout(function(){e++;b(e);if(e>=g-1){c()}else{a()}},h-new Date().getTime())})()};Dygraph.isPixelChangingOptionList=function(h,e){var d={annotationClickHandler:true,annotationDblClickHandler:true,annotationMouseOutHandler:true,annotationMouseOverHandler:true,axisLabelColor:true,axisLineColor:true,axisLineWidth:true,clickCallback:true,digitsAfterDecimal:true,drawCallback:true,drawPoints:true,drawXGrid:true,drawYGrid:true,fillAlpha:true,gridLineColor:true,gridLineWidth:true,hideOverlayOnMouseOut:true,highlightCallback:true,highlightCircleSize:true,interactionModel:true,isZoomedIgnoreProgrammaticZoom:true,labelsDiv:true,labelsDivStyles:true,labelsDivWidth:true,labelsKMB:true,labelsKMG2:true,labelsSeparateLines:true,labelsShowZeroValues:true,legend:true,maxNumberWidth:true,panEdgeFraction:true,pixelsPerYLabel:true,pointClickCallback:true,pointSize:true,rangeSelectorPlotFillColor:true,rangeSelectorPlotStrokeColor:true,showLabelsOnHighlight:true,showRoller:true,sigFigs:true,strokeWidth:true,underlayCallback:true,unhighlightCallback:true,xAxisLabelFormatter:true,xTicker:true,xValueFormatter:true,yAxisLabelFormatter:true,yValueFormatter:true,zoomCallback:true};var a=false;var b={};if(h){for(var f=1;f<h.length;f++){b[h[f]]=true}}for(var g in e){if(a){break}if(e.hasOwnProperty(g)){if(b[g]){for(var c in e[g]){if(a){break}if(e[g].hasOwnProperty(c)&&!d[c]){a=true}}}else{if(!d[g]){a=true}}}}return a};"use strict";Dygraph.GVizChart=function(a){this.container=a};Dygraph.GVizChart.prototype.draw=function(b,a){this.container.innerHTML="";if(typeof(this.date_graph)!="undefined"){this.date_graph.destroy()}this.date_graph=new Dygraph(this.container,b,a)};Dygraph.GVizChart.prototype.setSelection=function(b){var a=false;if(b.length){a=b[0].row}this.date_graph.setSelection(a)};Dygraph.GVizChart.prototype.getSelection=function(){var d=[];var e=this.date_graph.getSelection();if(e<0){return d}var b=1;var c=this.date_graph.layout_.datasets;for(var a in c){if(!c.hasOwnProperty(a)){continue}d.push({row:e,column:b});b++}return d};"use strict";Dygraph.Interaction={};Dygraph.Interaction.startPan=function(n,s,c){var q,b;c.isPanning=true;var j=s.xAxisRange();c.dateRange=j[1]-j[0];c.initialLeftmostDate=j[0];c.xUnitsPerPixel=c.dateRange/(s.plotter_.area.w-1);if(s.attr_("panEdgeFraction")){var v=s.width_*s.attr_("panEdgeFraction");var d=s.xAxisExtremes();var h=s.toDomXCoord(d[0])-v;var k=s.toDomXCoord(d[1])+v;var t=s.toDataXCoord(h);var u=s.toDataXCoord(k);c.boundedDates=[t,u];var f=[];var a=s.height_*s.attr_("panEdgeFraction");for(q=0;q<s.axes_.length;q++){b=s.axes_[q];var o=b.extremeRange;var p=s.toDomYCoord(o[0],q)+a;var r=s.toDomYCoord(o[1],q)-a;var m=s.toDataYCoord(p);var e=s.toDataYCoord(r);f[q]=[m,e]}c.boundedValues=f}c.is2DPan=false;for(q=0;q<s.axes_.length;q++){b=s.axes_[q];var l=s.yAxisRange(q);if(b.logscale){b.initialTopValue=Dygraph.log10(l[1]);b.dragValueRange=Dygraph.log10(l[1])-Dygraph.log10(l[0])}else{b.initialTopValue=l[1];b.dragValueRange=l[1]-l[0]}b.unitsPerPixel=b.dragValueRange/(s.plotter_.area.h-1);if(b.valueWindow||b.valueRange){c.is2DPan=true}}};Dygraph.Interaction.movePan=function(b,k,c){c.dragEndX=k.dragGetX_(b,c);c.dragEndY=k.dragGetY_(b,c);var h=c.initialLeftmostDate-(c.dragEndX-c.dragStartX)*c.xUnitsPerPixel;if(c.boundedDates){h=Math.max(h,c.boundedDates[0])}var a=h+c.dateRange;if(c.boundedDates){if(a>c.boundedDates[1]){h=h-(a-c.boundedDates[1]);a=h+c.dateRange}}k.dateWindow_=[h,a];if(c.is2DPan){for(var j=0;j<k.axes_.length;j++){var e=k.axes_[j];var d=c.dragEndY-c.dragStartY;var n=d*e.unitsPerPixel;var f=c.boundedValues?c.boundedValues[j]:null;var l=e.initialTopValue+n;if(f){l=Math.min(l,f[1])}var m=l-e.dragValueRange;if(f){if(m<f[0]){l=l-(m-f[0]);m=l-e.dragValueRange}}if(e.logscale){e.valueWindow=[Math.pow(Dygraph.LOG_SCALE,m),Math.pow(Dygraph.LOG_SCALE,l)]}else{e.valueWindow=[m,l]}}}k.drawGraph_(false)};Dygraph.Interaction.endPan=function(c,b,a){a.dragEndX=b.dragGetX_(c,a);a.dragEndY=b.dragGetY_(c,a);var e=Math.abs(a.dragEndX-a.dragStartX);var d=Math.abs(a.dragEndY-a.dragStartY);if(e<2&&d<2&&b.lastx_!==undefined&&b.lastx_!=-1){Dygraph.Interaction.treatMouseOpAsClick(b,c,a)}a.isPanning=false;a.is2DPan=false;a.initialLeftmostDate=null;a.dateRange=null;a.valueRange=null;a.boundedDates=null;a.boundedValues=null};Dygraph.Interaction.startZoom=function(c,b,a){a.isZooming=true};Dygraph.Interaction.moveZoom=function(c,b,a){a.dragEndX=b.dragGetX_(c,a);a.dragEndY=b.dragGetY_(c,a);var e=Math.abs(a.dragStartX-a.dragEndX);var d=Math.abs(a.dragStartY-a.dragEndY);a.dragDirection=(e<d/2)?Dygraph.VERTICAL:Dygraph.HORIZONTAL;b.drawZoomRect_(a.dragDirection,a.dragStartX,a.dragEndX,a.dragStartY,a.dragEndY,a.prevDragDirection,a.prevEndX,a.prevEndY);a.prevEndX=a.dragEndX;a.prevEndY=a.dragEndY;a.prevDragDirection=a.dragDirection};Dygraph.Interaction.treatMouseOpAsClick=function(f,b,d){var k=f.attr_("clickCallback");var n=f.attr_("pointClickCallback");var j=null;if(n){var l=-1;var m=Number.MAX_VALUE;for(var e=0;e<f.selPoints_.length;e++){var c=f.selPoints_[e];var a=Math.pow(c.canvasx-d.dragEndX,2)+Math.pow(c.canvasy-d.dragEndY,2);if(!isNaN(a)&&(l==-1||a<m)){m=a;l=e}}var h=f.attr_("highlightCircleSize")+2;if(m<=h*h){j=f.selPoints_[l]}}if(j){n(b,j)}if(k){k(b,f.lastx_,f.selPoints_)}};Dygraph.Interaction.endZoom=function(c,b,a){a.isZooming=false;a.dragEndX=b.dragGetX_(c,a);a.dragEndY=b.dragGetY_(c,a);var e=Math.abs(a.dragEndX-a.dragStartX);var d=Math.abs(a.dragEndY-a.dragStartY);if(e<2&&d<2&&b.lastx_!==undefined&&b.lastx_!=-1){Dygraph.Interaction.treatMouseOpAsClick(b,c,a)}if(e>=10&&a.dragDirection==Dygraph.HORIZONTAL){b.doZoomX_(Math.min(a.dragStartX,a.dragEndX),Math.max(a.dragStartX,a.dragEndX))}else{if(d>=10&&a.dragDirection==Dygraph.VERTICAL){b.doZoomY_(Math.min(a.dragStartY,a.dragEndY),Math.max(a.dragStartY,a.dragEndY))}else{b.clearZoomRect_()}}a.dragStartX=null;a.dragStartY=null};Dygraph.Interaction.defaultModel={mousedown:function(c,b,a){a.initializeMouseDown(c,b,a);if(c.altKey||c.shiftKey){Dygraph.startPan(c,b,a)}else{Dygraph.startZoom(c,b,a)}},mousemove:function(c,b,a){if(a.isZooming){Dygraph.moveZoom(c,b,a)}else{if(a.isPanning){Dygraph.movePan(c,b,a)}}},mouseup:function(c,b,a){if(a.isZooming){Dygraph.endZoom(c,b,a)}else{if(a.isPanning){Dygraph.endPan(c,b,a)}}},mouseout:function(c,b,a){if(a.isZooming){a.dragEndX=null;a.dragEndY=null}},dblclick:function(c,b,a){if(c.altKey||c.shiftKey){return}b.doUnzoom_()}};Dygraph.DEFAULT_ATTRS.interactionModel=Dygraph.Interaction.defaultModel;Dygraph.defaultInteractionModel=Dygraph.Interaction.defaultModel;Dygraph.endZoom=Dygraph.Interaction.endZoom;Dygraph.moveZoom=Dygraph.Interaction.moveZoom;Dygraph.startZoom=Dygraph.Interaction.startZoom;Dygraph.endPan=Dygraph.Interaction.endPan;Dygraph.movePan=Dygraph.Interaction.movePan;Dygraph.startPan=Dygraph.Interaction.startPan;Dygraph.Interaction.nonInteractiveModel_={mousedown:function(c,b,a){a.initializeMouseDown(c,b,a)},mouseup:function(c,b,a){a.dragEndX=b.dragGetX_(c,a);a.dragEndY=b.dragGetY_(c,a);var e=Math.abs(a.dragEndX-a.dragStartX);var d=Math.abs(a.dragEndY-a.dragStartY);if(e<2&&d<2&&b.lastx_!==undefined&&b.lastx_!=-1){Dygraph.Interaction.treatMouseOpAsClick(b,c,a)}}};"use strict";var DygraphRangeSelector=function(a){this.isIE_=/MSIE/.test(navigator.userAgent)&&!window.opera;this.isUsingExcanvas_=a.isUsingExcanvas_;this.dygraph_=a;this.createCanvases_();if(this.isUsingExcanvas_){this.createIEPanOverlay_()}this.createZoomHandles_();this.initInteraction_()};DygraphRangeSelector.prototype.addToGraph=function(a,b){this.layout_=b;this.resize_();a.appendChild(this.bgcanvas_);a.appendChild(this.fgcanvas_);a.appendChild(this.leftZoomHandle_);a.appendChild(this.rightZoomHandle_)};DygraphRangeSelector.prototype.renderStaticLayer=function(){this.resize_();this.drawStaticLayer_()};DygraphRangeSelector.prototype.renderInteractiveLayer=function(){if(this.isChangingRange_){return}this.placeZoomHandles_();this.drawInteractiveLayer_()};DygraphRangeSelector.prototype.resize_=function(){function c(d,e){d.style.top=e.y+"px";d.style.left=e.x+"px";d.width=e.w;d.height=e.h;d.style.width=d.width+"px";d.style.height=d.height+"px"}var b=this.layout_.getPlotArea();var a=this.attr_("axisLabelFontSize")+2*this.attr_("axisTickSize");this.canvasRect_={x:b.x,y:b.y+b.h+a+4,w:b.w,h:this.attr_("rangeSelectorHeight")};c(this.bgcanvas_,this.canvasRect_);c(this.fgcanvas_,this.canvasRect_)};DygraphRangeSelector.prototype.attr_=function(a){return this.dygraph_.attr_(a)};DygraphRangeSelector.prototype.createCanvases_=function(){this.bgcanvas_=Dygraph.createCanvas();this.bgcanvas_.className="dygraph-rangesel-bgcanvas";this.bgcanvas_.style.position="absolute";this.bgcanvas_.style.zIndex=9;this.bgcanvas_ctx_=Dygraph.getContext(this.bgcanvas_);this.fgcanvas_=Dygraph.createCanvas();this.fgcanvas_.className="dygraph-rangesel-fgcanvas";this.fgcanvas_.style.position="absolute";this.fgcanvas_.style.zIndex=9;this.fgcanvas_.style.cursor="default";this.fgcanvas_ctx_=Dygraph.getContext(this.fgcanvas_)};DygraphRangeSelector.prototype.createIEPanOverlay_=function(){this.iePanOverlay_=document.createElement("div");this.iePanOverlay_.style.position="absolute";this.iePanOverlay_.style.backgroundColor="white";this.iePanOverlay_.style.filter="alpha(opacity=0)";this.iePanOverlay_.style.display="none";this.iePanOverlay_.style.cursor="move";this.fgcanvas_.appendChild(this.iePanOverlay_)};DygraphRangeSelector.prototype.createZoomHandles_=function(){var a=new Image();a.className="dygraph-rangesel-zoomhandle";a.style.position="absolute";a.style.zIndex=10;a.style.visibility="hidden";a.style.cursor="col-resize";if(/MSIE 7/.test(navigator.userAgent)){a.width=7;a.height=14;a.style.backgroundColor="white";a.style.border="1px solid #333333"}else{a.width=9;a.height=16;a.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAQCAYAAADESFVDAAAAAXNSR0IArs4c6QAAAAZiS0dEANAAzwDP4Z7KegAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB9sHGw0cMqdt1UwAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAaElEQVQoz+3SsRFAQBCF4Z9WJM8KCDVwownl6YXsTmCUsyKGkZzcl7zkz3YLkypgAnreFmDEpHkIwVOMfpdi9CEEN2nGpFdwD03yEqDtOgCaun7sqSTDH32I1pQA2Pb9sZecAxc5r3IAb21d6878xsAAAAAASUVORK5CYII="}this.leftZoomHandle_=a;this.rightZoomHandle_=a.cloneNode(false)};DygraphRangeSelector.prototype.initInteraction_=function(){var i=this;var f=this.isIE_?document:window;var k=0;var p=null;var n=false;var c=false;var j,d,m,g,r,e,s,o,l,b,h;j=function(x){var w=i.dygraph_.xAxisExtremes();var u=(w[1]-w[0])/i.canvasRect_.w;var v=w[0]+(x.leftHandlePos-i.canvasRect_.x)*u;var t=w[0]+(x.rightHandlePos-i.canvasRect_.x)*u;return[v,t]};d=function(t){Dygraph.cancelEvent(t);n=true;k=t.screenX;p=t.target?t.target:t.srcElement;Dygraph.addEvent(f,"mousemove",m);Dygraph.addEvent(f,"mouseup",g);i.fgcanvas_.style.cursor="col-resize"};m=function(x){if(!n){return}var u=x.screenX-k;if(Math.abs(u)<4){return}k=x.screenX;var w=i.getZoomHandleStatus_();var t;if(p==i.leftZoomHandle_){t=w.leftHandlePos+u;t=Math.min(t,w.rightHandlePos-p.width-3);t=Math.max(t,i.canvasRect_.x)}else{t=w.rightHandlePos+u;t=Math.min(t,i.canvasRect_.x+i.canvasRect_.w);t=Math.max(t,w.leftHandlePos+p.width+3)}var v=p.width/2;p.style.left=(t-v)+"px";i.drawInteractiveLayer_();if(!i.isUsingExcanvas_){r()}};g=function(t){if(!n){return}n=false;Dygraph.removeEvent(f,"mousemove",m);Dygraph.removeEvent(f,"mouseup",g);i.fgcanvas_.style.cursor="default";if(i.isUsingExcanvas_){r()}};r=function(){try{var u=i.getZoomHandleStatus_();i.isChangingRange_=true;if(!u.isZoomed){i.dygraph_.doUnzoom_()}else{var t=j(u);i.dygraph_.doZoomXDates_(t[0],t[1])}}finally{i.isChangingRange_=false}};e=function(v){if(i.isUsingExcanvas_){return v.srcElement==i.iePanOverlay_}else{var t=i.canvasRect_.x+(v.layerX!==undefined?v.layerX:v.offsetX);var u=i.getZoomHandleStatus_();return(t>u.leftHandlePos&&t<u.rightHandlePos)}};s=function(t){if(!c&&e(t)&&i.getZoomHandleStatus_().isZoomed){Dygraph.cancelEvent(t);c=true;k=t.screenX;Dygraph.addEvent(f,"mousemove",o);Dygraph.addEvent(f,"mouseup",l)}};o=function(x){if(!c){return}Dygraph.cancelEvent(x);var u=x.screenX-k;if(Math.abs(u)<4){return}k=x.screenX;var w=i.getZoomHandleStatus_();var z=w.leftHandlePos;var t=w.rightHandlePos;var y=t-z;if(z+u<=i.canvasRect_.x){z=i.canvasRect_.x;t=z+y}else{if(t+u>=i.canvasRect_.x+i.canvasRect_.w){t=i.canvasRect_.x+i.canvasRect_.w;z=t-y}else{z+=u;t+=u}}var v=i.leftZoomHandle_.width/2;i.leftZoomHandle_.style.left=(z-v)+"px";i.rightZoomHandle_.style.left=(t-v)+"px";i.drawInteractiveLayer_();if(!i.isUsingExcanvas_){b()}};l=function(t){if(!c){return}c=false;Dygraph.removeEvent(f,"mousemove",o);Dygraph.removeEvent(f,"mouseup",l);if(i.isUsingExcanvas_){b()}};b=function(){try{i.isChangingRange_=true;i.dygraph_.dateWindow_=j(i.getZoomHandleStatus_());i.dygraph_.drawGraph_(false)}finally{i.isChangingRange_=false}};h=function(t){if(n||c){return}var u=e(t)?"move":"default";if(u!=i.fgcanvas_.style.cursor){i.fgcanvas_.style.cursor=u}};var q={mousedown:function(v,u,t){t.initializeMouseDown(v,u,t);Dygraph.startPan(v,u,t)},mousemove:function(v,u,t){if(t.isPanning){Dygraph.movePan(v,u,t)}},mouseup:function(v,u,t){if(t.isPanning){Dygraph.endPan(v,u,t)}}};this.dygraph_.attrs_.interactionModel=q;this.dygraph_.attrs_.panEdgeFraction=0.0001;var a=window.opera?"mousedown":"dragstart";Dygraph.addEvent(this.leftZoomHandle_,a,d);Dygraph.addEvent(this.rightZoomHandle_,a,d);if(this.isUsingExcanvas_){Dygraph.addEvent(this.iePanOverlay_,"mousedown",s)}else{Dygraph.addEvent(this.fgcanvas_,"mousedown",s);Dygraph.addEvent(this.fgcanvas_,"mousemove",h)}};DygraphRangeSelector.prototype.drawStaticLayer_=function(){var a=this.bgcanvas_ctx_;a.clearRect(0,0,this.canvasRect_.w,this.canvasRect_.h);try{this.drawMiniPlot_()}catch(b){Dygraph.warn(b)}var c=0.5;this.bgcanvas_ctx_.lineWidth=1;a.strokeStyle="gray";a.beginPath();a.moveTo(c,c);a.lineTo(c,this.canvasRect_.h-c);a.lineTo(this.canvasRect_.w-c,this.canvasRect_.h-c);a.lineTo(this.canvasRect_.w-c,c);a.stroke()};DygraphRangeSelector.prototype.drawMiniPlot_=function(){var p=this.attr_("rangeSelectorPlotFillColor");var l=this.attr_("rangeSelectorPlotStrokeColor");if(!p&&!l){return}var m=this.computeCombinedSeriesAndLimits_();var e=m.yMax-m.yMin;var r=this.bgcanvas_ctx_;var f=0.5;var j=this.dygraph_.xAxisExtremes();var b=Math.max(j[1]-j[0],1e-30);var q=(this.canvasRect_.w-f)/b;var o=(this.canvasRect_.h-f)/e;var d=this.canvasRect_.w-f;var h=this.canvasRect_.h-f;r.beginPath();r.moveTo(f,h);for(var g=0;g<m.data.length;g++){var a=m.data[g];var n=(a[0]-j[0])*q;var k=h-(a[1]-m.yMin)*o;if(isFinite(n)&&isFinite(k)){r.lineTo(n,k)}}r.lineTo(d,h);r.closePath();if(p){var c=this.bgcanvas_ctx_.createLinearGradient(0,0,0,h);c.addColorStop(0,"white");c.addColorStop(1,p);this.bgcanvas_ctx_.fillStyle=c;r.fill()}if(l){this.bgcanvas_ctx_.strokeStyle=l;this.bgcanvas_ctx_.lineWidth=1.5;r.stroke()}};DygraphRangeSelector.prototype.computeCombinedSeriesAndLimits_=function(){var u=this.dygraph_.rawData_;var t=this.attr_("logscale");var p=[];var c;var g;var f,m;var l;var s,r,q;for(s=0;s<u.length;s++){if(u[s].length>1&&u[s][1]!=null){l=typeof u[s][1]!="number";if(l){c=[];g=[];for(q=0;q<u[s][1].length;q++){c.push(0);g.push(0)}}break}}for(s=0;s<u.length;s++){var h=u[s];var d=h[0];if(l){for(q=0;q<c.length;q++){c[q]=g[q]=0}}else{c=g=0}for(r=1;r<h.length;r++){if(this.dygraph_.visibility()[r-1]){if(l){for(q=0;q<c.length;q++){m=h[r][q];if(m===null||isNaN(m)){continue}c[q]+=m;g[q]++}}else{m=h[r];if(m===null||isNaN(m)){continue}c+=m;g++}}}if(l){for(q=0;q<c.length;q++){c[q]/=g[q]}f=c.slice(0)}else{f=c/g}p.push([d,f])}p=this.dygraph_.rollingAverage(p,this.dygraph_.rollPeriod_);if(typeof p[0][1]!="number"){for(s=0;s<p.length;s++){f=p[s][1];p[s][1]=f[0]}}var a=Number.MAX_VALUE;var b=-Number.MAX_VALUE;for(s=0;s<p.length;s++){f=p[s][1];if(f!==null&&isFinite(f)&&(!t||f>0)){a=Math.min(a,f);b=Math.max(b,f)}}var n=0.25;if(t){b=Dygraph.log10(b);b+=b*n;a=Dygraph.log10(a);for(s=0;s<p.length;s++){p[s][1]=Dygraph.log10(p[s][1])}}else{var e;var o=b-a;if(o<=Number.MIN_VALUE){e=b*n}else{e=o*n}b+=e;a-=e}return{data:p,yMin:a,yMax:b}};DygraphRangeSelector.prototype.placeZoomHandles_=function(){var g=this.dygraph_.xAxisExtremes();var a=this.dygraph_.xAxisRange();var b=g[1]-g[0];var i=Math.max(0,(a[0]-g[0])/b);var e=Math.max(0,(g[1]-a[1])/b);var h=this.canvasRect_.x+this.canvasRect_.w*i;var d=this.canvasRect_.x+this.canvasRect_.w*(1-e);var c=Math.max(this.canvasRect_.y,this.canvasRect_.y+(this.canvasRect_.h-this.leftZoomHandle_.height)/2);var f=this.leftZoomHandle_.width/2;this.leftZoomHandle_.style.left=(h-f)+"px";this.leftZoomHandle_.style.top=c+"px";this.rightZoomHandle_.style.left=(d-f)+"px";this.rightZoomHandle_.style.top=this.leftZoomHandle_.style.top;this.leftZoomHandle_.style.visibility="visible";this.rightZoomHandle_.style.visibility="visible"};DygraphRangeSelector.prototype.drawInteractiveLayer_=function(){var b=this.fgcanvas_ctx_;b.clearRect(0,0,this.canvasRect_.w,this.canvasRect_.h);var e=1;var d=this.canvasRect_.w-e;var a=this.canvasRect_.h-e;var g=this.getZoomHandleStatus_();b.strokeStyle="black";if(!g.isZoomed){b.beginPath();b.moveTo(e,e);b.lineTo(e,a);b.lineTo(d,a);b.lineTo(d,e);b.stroke();if(this.iePanOverlay_){this.iePanOverlay_.style.display="none"}}else{var f=Math.max(e,g.leftHandlePos-this.canvasRect_.x);var c=Math.min(d,g.rightHandlePos-this.canvasRect_.x);b.fillStyle="rgba(240, 240, 240, 0.6)";b.fillRect(0,0,f,this.canvasRect_.h);b.fillRect(c,0,this.canvasRect_.w-c,this.canvasRect_.h);b.beginPath();b.moveTo(e,e);b.lineTo(f,e);b.lineTo(f,a);b.lineTo(c,a);b.lineTo(c,e);b.lineTo(d,e);b.stroke();if(this.isUsingExcanvas_){this.iePanOverlay_.style.width=(c-f)+"px";this.iePanOverlay_.style.left=f+"px";this.iePanOverlay_.style.height=a+"px";this.iePanOverlay_.style.display="inline"}}};DygraphRangeSelector.prototype.getZoomHandleStatus_=function(){var b=this.leftZoomHandle_.width/2;var c=parseInt(this.leftZoomHandle_.style.left,10)+b;var a=parseInt(this.rightZoomHandle_.style.left,10)+b;return{leftHandlePos:c,rightHandlePos:a,isZoomed:(c-1>this.canvasRect_.x||a+1<this.canvasRect_.x+this.canvasRect_.w)}};"use strict";Dygraph.numericTicks=function(I,H,w,r,d,s){var C=r("pixelsPerLabel");var J=[];var F,D,v,A;if(s){for(F=0;F<s.length;F++){J.push({v:s[F]})}}else{if(r("logscale")){A=Math.floor(w/C);var o=Dygraph.binarySearch(I,Dygraph.PREFERRED_LOG_TICK_VALUES,1);var K=Dygraph.binarySearch(H,Dygraph.PREFERRED_LOG_TICK_VALUES,-1);if(o==-1){o=0}if(K==-1){K=Dygraph.PREFERRED_LOG_TICK_VALUES.length-1}var u=null;if(K-o>=A/4){for(var t=K;t>=o;t--){var p=Dygraph.PREFERRED_LOG_TICK_VALUES[t];var m=Math.log(p/I)/Math.log(H/I)*w;var G={v:p};if(u===null){u={tickValue:p,pixel_coord:m}}else{if(Math.abs(m-u.pixel_coord)>=C){u={tickValue:p,pixel_coord:m}}else{G.label=""}}J.push(G)}J.reverse()}}if(J.length===0){var h=r("labelsKMG2");var q;if(h){q=[1,2,4,8]}else{q=[1,2,5]}var L,z,c;for(F=-10;F<50;F++){var g;if(h){g=Math.pow(16,F)}else{g=Math.pow(10,F)}var f=0;for(D=0;D<q.length;D++){L=g*q[D];z=Math.floor(I/L)*L;c=Math.ceil(H/L)*L;A=Math.abs(c-z)/L;f=w/A;if(f>C){break}}if(f>C){break}}if(z>c){L*=-1}for(F=0;F<A;F++){v=z+F*L;J.push({v:v})}}}var B;var y=[];if(r("labelsKMB")){B=1000;y=["K","M","B","T"]}if(r("labelsKMG2")){if(B){Dygraph.warn("Setting both labelsKMB and labelsKMG2. Pick one!")}B=1024;y=["k","M","G","T"]}var E=r("axisLabelFormatter");for(F=0;F<J.length;F++){if(J[F].label!==undefined){continue}v=J[F].v;var e=Math.abs(v);var l=E(v,0,r,d);if(y.length>0){var x=B*B*B*B;for(D=3;D>=0;D--,x/=B){if(e>=x){l=Dygraph.round_(v/x,r("digitsAfterDecimal"))+y[D];break}}}J[F].label=l}return J};Dygraph.dateTicker=function(e,c,i,g,f,h){var d=Dygraph.pickDateTickGranularity(e,c,i,g);if(d>=0){return Dygraph.getDateAxis(e,c,d,g,f)}else{return[]}};Dygraph.SECONDLY=0;Dygraph.TWO_SECONDLY=1;Dygraph.FIVE_SECONDLY=2;Dygraph.TEN_SECONDLY=3;Dygraph.THIRTY_SECONDLY=4;Dygraph.MINUTELY=5;Dygraph.TWO_MINUTELY=6;Dygraph.FIVE_MINUTELY=7;Dygraph.TEN_MINUTELY=8;Dygraph.THIRTY_MINUTELY=9;Dygraph.HOURLY=10;Dygraph.TWO_HOURLY=11;Dygraph.SIX_HOURLY=12;Dygraph.DAILY=13;Dygraph.WEEKLY=14;Dygraph.MONTHLY=15;Dygraph.QUARTERLY=16;Dygraph.BIANNUAL=17;Dygraph.ANNUAL=18;Dygraph.DECADAL=19;Dygraph.CENTENNIAL=20;Dygraph.NUM_GRANULARITIES=21;Dygraph.SHORT_SPACINGS=[];Dygraph.SHORT_SPACINGS[Dygraph.SECONDLY]=1000*1;Dygraph.SHORT_SPACINGS[Dygraph.TWO_SECONDLY]=1000*2;Dygraph.SHORT_SPACINGS[Dygraph.FIVE_SECONDLY]=1000*5;Dygraph.SHORT_SPACINGS[Dygraph.TEN_SECONDLY]=1000*10;Dygraph.SHORT_SPACINGS[Dygraph.THIRTY_SECONDLY]=1000*30;Dygraph.SHORT_SPACINGS[Dygraph.MINUTELY]=1000*60;Dygraph.SHORT_SPACINGS[Dygraph.TWO_MINUTELY]=1000*60*2;Dygraph.SHORT_SPACINGS[Dygraph.FIVE_MINUTELY]=1000*60*5;Dygraph.SHORT_SPACINGS[Dygraph.TEN_MINUTELY]=1000*60*10;Dygraph.SHORT_SPACINGS[Dygraph.THIRTY_MINUTELY]=1000*60*30;Dygraph.SHORT_SPACINGS[Dygraph.HOURLY]=1000*3600;Dygraph.SHORT_SPACINGS[Dygraph.TWO_HOURLY]=1000*3600*2;Dygraph.SHORT_SPACINGS[Dygraph.SIX_HOURLY]=1000*3600*6;Dygraph.SHORT_SPACINGS[Dygraph.DAILY]=1000*86400;Dygraph.SHORT_SPACINGS[Dygraph.WEEKLY]=1000*604800;Dygraph.PREFERRED_LOG_TICK_VALUES=function(){var c=[];for(var b=-39;b<=39;b++){var a=Math.pow(10,b);for(var d=1;d<=9;d++){var e=a*d;c.push(e)}}return c}();Dygraph.pickDateTickGranularity=function(d,c,j,h){var g=h("pixelsPerLabel");for(var f=0;f<Dygraph.NUM_GRANULARITIES;f++){var e=Dygraph.numDateTicks(d,c,f);if(j/e>=g){return f}}return -1};Dygraph.numDateTicks=function(e,b,g){if(g<Dygraph.MONTHLY){var h=Dygraph.SHORT_SPACINGS[g];return Math.floor(0.5+1*(b-e)/h)}else{var f=1;var d=12;if(g==Dygraph.QUARTERLY){d=3}if(g==Dygraph.BIANNUAL){d=2}if(g==Dygraph.ANNUAL){d=1}if(g==Dygraph.DECADAL){d=1;f=10}if(g==Dygraph.CENTENNIAL){d=1;f=100}var c=365.2524*24*3600*1000;var a=1*(b-e)/c;return Math.floor(0.5+1*a*d/f)}};Dygraph.getDateAxis=function(n,h,a,l,w){var u=l("axisLabelFormatter");var z=[];var k;if(a<Dygraph.MONTHLY){var c=Dygraph.SHORT_SPACINGS[a];var v=c/1000;var y=new Date(n);var f;if(v<=60){f=y.getSeconds();y.setSeconds(f-f%v)}else{y.setSeconds(0);v/=60;if(v<=60){f=y.getMinutes();y.setMinutes(f-f%v)}else{y.setMinutes(0);v/=60;if(v<=24){f=y.getHours();y.setHours(f-f%v)}else{y.setHours(0);v/=24;if(v==7){y.setDate(y.getDate()-y.getDay())}}}}n=y.getTime();for(k=n;k<=h;k+=c){z.push({v:k,label:u(new Date(k),a,l,w)})}}else{var e;var o=1;if(a==Dygraph.MONTHLY){e=[0,1,2,3,4,5,6,7,8,9,10,11]}else{if(a==Dygraph.QUARTERLY){e=[0,3,6,9]}else{if(a==Dygraph.BIANNUAL){e=[0,6]}else{if(a==Dygraph.ANNUAL){e=[0]}else{if(a==Dygraph.DECADAL){e=[0];o=10}else{if(a==Dygraph.CENTENNIAL){e=[0];o=100}else{Dygraph.warn("Span of dates is too long")}}}}}}var s=new Date(n).getFullYear();var p=new Date(h).getFullYear();var b=Dygraph.zeropad;for(var r=s;r<=p;r++){if(r%o!==0){continue}for(var q=0;q<e.length;q++){var m=r+"/"+b(1+e[q])+"/01";k=Dygraph.dateStrToMillis(m);if(k<n||k>h){continue}z.push({v:k,label:u(new Date(k),a,l,w)})}}}return z};Dygraph.DEFAULT_ATTRS.axes.x.ticker=Dygraph.dateTicker;Dygraph.DEFAULT_ATTRS.axes.y.ticker=Dygraph.numericTicks;Dygraph.DEFAULT_ATTRS.axes.y2.ticker=Dygraph.numericTicks;"use strict";function RGBColor(f){this.ok=false;if(f.charAt(0)=="#"){f=f.substr(1,6)}f=f.replace(/ /g,"");f=f.toLowerCase();var b={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"00ffff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000000",blanchedalmond:"ffebcd",blue:"0000ff",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"00ffff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dodgerblue:"1e90ff",feldspar:"d19275",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"ff00ff",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgrey:"d3d3d3",lightgreen:"90ee90",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslateblue:"8470ff",lightslategray:"778899",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"00ff00",limegreen:"32cd32",linen:"faf0e6",magenta:"ff00ff",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370d8",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"d87093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",red:"ff0000",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",violetred:"d02090",wheat:"f5deb3",white:"ffffff",whitesmoke:"f5f5f5",yellow:"ffff00",yellowgreen:"9acd32"};for(var g in b){if(f==g){f=b[g]}}var e=[{re:/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,example:["rgb(123, 234, 45)","rgb(255,234,245)"],process:function(i){return[parseInt(i[1]),parseInt(i[2]),parseInt(i[3])]}},{re:/^(\w{2})(\w{2})(\w{2})$/,example:["#00ff00","336699"],process:function(i){return[parseInt(i[1],16),parseInt(i[2],16),parseInt(i[3],16)]}},{re:/^(\w{1})(\w{1})(\w{1})$/,example:["#fb0","f0f"],process:function(i){return[parseInt(i[1]+i[1],16),parseInt(i[2]+i[2],16),parseInt(i[3]+i[3],16)]}}];for(var c=0;c<e.length;c++){var j=e[c].re;var a=e[c].process;var h=j.exec(f);if(h){var d=a(h);this.r=d[0];this.g=d[1];this.b=d[2];this.ok=true}}this.r=(this.r<0||isNaN(this.r))?0:((this.r>255)?255:this.r);this.g=(this.g<0||isNaN(this.g))?0:((this.g>255)?255:this.g);this.b=(this.b<0||isNaN(this.b))?0:((this.b>255)?255:this.b);this.toRGB=function(){return"rgb("+this.r+", "+this.g+", "+this.b+")"};this.toHex=function(){var l=this.r.toString(16);var k=this.g.toString(16);var i=this.b.toString(16);if(l.length==1){l="0"+l}if(k.length==1){k="0"+k}if(i.length==1){i="0"+i}return"#"+l+k+i}}Date.ext={};Date.ext.util={};Date.ext.util.xPad=function(a,c,b){if(typeof(b)=="undefined"){b=10}for(;parseInt(a,10)<b&&b>1;b/=10){a=c.toString()+a}return a.toString()};Date.prototype.locale="en-GB";if(document.getElementsByTagName("html")&&document.getElementsByTagName("html")[0].lang){Date.prototype.locale=document.getElementsByTagName("html")[0].lang}Date.ext.locales={};Date.ext.locales.en={a:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],A:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],b:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],B:["January","February","March","April","May","June","July","August","September","October","November","December"],c:"%a %d %b %Y %T %Z",p:["AM","PM"],P:["am","pm"],x:"%d/%m/%y",X:"%T"};Date.ext.locales["en-US"]=Date.ext.locales.en;Date.ext.locales["en-US"].c="%a %d %b %Y %r %Z";Date.ext.locales["en-US"].x="%D";Date.ext.locales["en-US"].X="%r";Date.ext.locales["en-GB"]=Date.ext.locales.en;Date.ext.locales["en-AU"]=Date.ext.locales["en-GB"];Date.ext.formats={a:function(a){return Date.ext.locales[a.locale].a[a.getDay()]},A:function(a){return Date.ext.locales[a.locale].A[a.getDay()]},b:function(a){return Date.ext.locales[a.locale].b[a.getMonth()]},B:function(a){return Date.ext.locales[a.locale].B[a.getMonth()]},c:"toLocaleString",C:function(a){return Date.ext.util.xPad(parseInt(a.getFullYear()/100,10),0)},d:["getDate","0"],e:["getDate"," "],g:function(a){return Date.ext.util.xPad(parseInt(Date.ext.util.G(a)/100,10),0)},G:function(c){var e=c.getFullYear();var b=parseInt(Date.ext.formats.V(c),10);var a=parseInt(Date.ext.formats.W(c),10);if(a>b){e++}else{if(a===0&&b>=52){e--}}return e},H:["getHours","0"],I:function(b){var a=b.getHours()%12;return Date.ext.util.xPad(a===0?12:a,0)},j:function(c){var a=c-new Date(""+c.getFullYear()+"/1/1 GMT");a+=c.getTimezoneOffset()*60000;var b=parseInt(a/60000/60/24,10)+1;return Date.ext.util.xPad(b,0,100)},m:function(a){return Date.ext.util.xPad(a.getMonth()+1,0)},M:["getMinutes","0"],p:function(a){return Date.ext.locales[a.locale].p[a.getHours()>=12?1:0]},P:function(a){return Date.ext.locales[a.locale].P[a.getHours()>=12?1:0]},S:["getSeconds","0"],u:function(a){var b=a.getDay();return b===0?7:b},U:function(e){var a=parseInt(Date.ext.formats.j(e),10);var c=6-e.getDay();var b=parseInt((a+c)/7,10);return Date.ext.util.xPad(b,0)},V:function(e){var c=parseInt(Date.ext.formats.W(e),10);var a=(new Date(""+e.getFullYear()+"/1/1")).getDay();var b=c+(a>4||a<=1?0:1);if(b==53&&(new Date(""+e.getFullYear()+"/12/31")).getDay()<4){b=1}else{if(b===0){b=Date.ext.formats.V(new Date(""+(e.getFullYear()-1)+"/12/31"))}}return Date.ext.util.xPad(b,0)},w:"getDay",W:function(e){var a=parseInt(Date.ext.formats.j(e),10);var c=7-Date.ext.formats.u(e);var b=parseInt((a+c)/7,10);return Date.ext.util.xPad(b,0,10)},y:function(a){return Date.ext.util.xPad(a.getFullYear()%100,0)},Y:"getFullYear",z:function(c){var b=c.getTimezoneOffset();var a=Date.ext.util.xPad(parseInt(Math.abs(b/60),10),0);var e=Date.ext.util.xPad(b%60,0);return(b>0?"-":"+")+a+e},Z:function(a){return a.toString().replace(/^.*\(([^)]+)\)$/,"$1")},"%":function(a){return"%"}};Date.ext.aggregates={c:"locale",D:"%m/%d/%y",h:"%b",n:"\n",r:"%I:%M:%S %p",R:"%H:%M",t:"\t",T:"%H:%M:%S",x:"locale",X:"locale"};Date.ext.aggregates.z=Date.ext.formats.z(new Date());Date.ext.aggregates.Z=Date.ext.formats.Z(new Date());Date.ext.unsupported={};Date.prototype.strftime=function(a){if(!(this.locale in Date.ext.locales)){if(this.locale.replace(/-[a-zA-Z]+$/,"") in Date.ext.locales){this.locale=this.locale.replace(/-[a-zA-Z]+$/,"")}else{this.locale="en-GB"}}var c=this;while(a.match(/%[cDhnrRtTxXzZ]/)){a=a.replace(/%([cDhnrRtTxXzZ])/g,function(e,d){var g=Date.ext.aggregates[d];return(g=="locale"?Date.ext.locales[c.locale][d]:g)})}var b=a.replace(/%([aAbBCdegGHIjmMpPSuUVwWyY%])/g,function(e,d){var g=Date.ext.formats[d];if(typeof(g)=="string"){return c[g]()}else{if(typeof(g)=="function"){return g.call(c,c)}else{if(typeof(g)=="object"&&typeof(g[0])=="string"){return Date.ext.util.xPad(c[g[0]](),g[1])}else{return d}}}});c=null;return b};
/trunk/plugins/ipfm/dygraph/excanvas.js
0,0 → 1,924
// Copyright 2006 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
 
 
// Known Issues:
//
// * Patterns are not implemented.
// * Radial gradient are not implemented. The VML version of these look very
// different from the canvas one.
// * Clipping paths are not implemented.
// * Coordsize. The width and height attribute have higher priority than the
// width and height style values which isn't correct.
// * Painting mode isn't implemented.
// * Canvas width/height should is using content-box by default. IE in
// Quirks mode will draw the canvas using border-box. Either change your
// doctype to HTML5
// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
// or use Box Sizing Behavior from WebFX
// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
// * Non uniform scaling does not correctly scale strokes.
// * Optimize. There is always room for speed improvements.
 
// Only add this code if we do not already have a canvas implementation
if (!document.createElement('canvas').getContext) {
 
(function() {
 
// alias some functions to make (compiled) code shorter
var m = Math;
var mr = m.round;
var ms = m.sin;
var mc = m.cos;
var abs = m.abs;
var sqrt = m.sqrt;
 
// this is used for sub pixel precision
var Z = 10;
var Z2 = Z / 2;
 
/**
* This funtion is assigned to the <canvas> elements as element.getContext().
* @this {HTMLElement}
* @return {CanvasRenderingContext2D_}
*/
function getContext() {
return this.context_ ||
(this.context_ = new CanvasRenderingContext2D_(this));
}
 
var slice = Array.prototype.slice;
 
/**
* Binds a function to an object. The returned function will always use the
* passed in {@code obj} as {@code this}.
*
* Example:
*
* g = bind(f, obj, a, b)
* g(c, d) // will do f.call(obj, a, b, c, d)
*
* @param {Function} f The function to bind the object to
* @param {Object} obj The object that should act as this when the function
* is called
* @param {*} var_args Rest arguments that will be used as the initial
* arguments when the function is called
* @return {Function} A new function that has bound this
*/
function bind(f, obj, var_args) {
var a = slice.call(arguments, 2);
return function() {
return f.apply(obj, a.concat(slice.call(arguments)));
};
}
 
var G_vmlCanvasManager_ = {
init: function(opt_doc) {
if (/MSIE/.test(navigator.userAgent) && !window.opera) {
var doc = opt_doc || document;
// Create a dummy element so that IE will allow canvas elements to be
// recognized.
doc.createElement('canvas');
doc.attachEvent('onreadystatechange', bind(this.init_, this, doc));
}
},
 
init_: function(doc) {
// create xmlns
if (!doc.namespaces['g_vml_']) {
doc.namespaces.add('g_vml_', 'urn:schemas-microsoft-com:vml',
'#default#VML');
 
}
if (!doc.namespaces['g_o_']) {
doc.namespaces.add('g_o_', 'urn:schemas-microsoft-com:office:office',
'#default#VML');
}
 
// Setup default CSS. Only add one style sheet per document
if (!doc.styleSheets['ex_canvas_']) {
var ss = doc.createStyleSheet();
ss.owningElement.id = 'ex_canvas_';
ss.cssText = 'canvas{display:inline-block;overflow:hidden;' +
// default size is 300x150 in Gecko and Opera
'text-align:left;width:300px;height:150px}' +
'g_vml_\\:*{behavior:url(#default#VML)}' +
'g_o_\\:*{behavior:url(#default#VML)}';
 
}
 
// find all canvas elements
var els = doc.getElementsByTagName('canvas');
for (var i = 0; i < els.length; i++) {
this.initElement(els[i]);
}
},
 
/**
* Public initializes a canvas element so that it can be used as canvas
* element from now on. This is called automatically before the page is
* loaded but if you are creating elements using createElement you need to
* make sure this is called on the element.
* @param {HTMLElement} el The canvas element to initialize.
* @return {HTMLElement} the element that was created.
*/
initElement: function(el) {
if (!el.getContext) {
 
el.getContext = getContext;
 
// Remove fallback content. There is no way to hide text nodes so we
// just remove all childNodes. We could hide all elements and remove
// text nodes but who really cares about the fallback content.
el.innerHTML = '';
 
// do not use inline function because that will leak memory
el.attachEvent('onpropertychange', onPropertyChange);
el.attachEvent('onresize', onResize);
 
var attrs = el.attributes;
if (attrs.width && attrs.width.specified) {
// TODO: use runtimeStyle and coordsize
// el.getContext().setWidth_(attrs.width.nodeValue);
el.style.width = attrs.width.nodeValue + 'px';
} else {
el.width = el.clientWidth;
}
if (attrs.height && attrs.height.specified) {
// TODO: use runtimeStyle and coordsize
// el.getContext().setHeight_(attrs.height.nodeValue);
el.style.height = attrs.height.nodeValue + 'px';
} else {
el.height = el.clientHeight;
}
//el.getContext().setCoordsize_()
}
return el;
}
};
 
function onPropertyChange(e) {
var el = e.srcElement;
 
switch (e.propertyName) {
case 'width':
el.style.width = el.attributes.width.nodeValue + 'px';
el.getContext().clearRect();
break;
case 'height':
el.style.height = el.attributes.height.nodeValue + 'px';
el.getContext().clearRect();
break;
}
}
 
function onResize(e) {
var el = e.srcElement;
if (el.firstChild) {
el.firstChild.style.width = el.clientWidth + 'px';
el.firstChild.style.height = el.clientHeight + 'px';
}
}
 
G_vmlCanvasManager_.init();
 
// precompute "00" to "FF"
var dec2hex = [];
for (var i = 0; i < 16; i++) {
for (var j = 0; j < 16; j++) {
dec2hex[i * 16 + j] = i.toString(16) + j.toString(16);
}
}
 
function createMatrixIdentity() {
return [
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]
];
}
 
function matrixMultiply(m1, m2) {
var result = createMatrixIdentity();
 
for (var x = 0; x < 3; x++) {
for (var y = 0; y < 3; y++) {
var sum = 0;
 
for (var z = 0; z < 3; z++) {
sum += m1[x][z] * m2[z][y];
}
 
result[x][y] = sum;
}
}
return result;
}
 
function copyState(o1, o2) {
o2.fillStyle = o1.fillStyle;
o2.lineCap = o1.lineCap;
o2.lineJoin = o1.lineJoin;
o2.lineWidth = o1.lineWidth;
o2.miterLimit = o1.miterLimit;
o2.shadowBlur = o1.shadowBlur;
o2.shadowColor = o1.shadowColor;
o2.shadowOffsetX = o1.shadowOffsetX;
o2.shadowOffsetY = o1.shadowOffsetY;
o2.strokeStyle = o1.strokeStyle;
o2.globalAlpha = o1.globalAlpha;
o2.arcScaleX_ = o1.arcScaleX_;
o2.arcScaleY_ = o1.arcScaleY_;
o2.lineScale_ = o1.lineScale_;
}
 
function processStyle(styleString) {
var str, alpha = 1;
 
styleString = String(styleString);
if (styleString.substring(0, 3) == 'rgb') {
var start = styleString.indexOf('(', 3);
var end = styleString.indexOf(')', start + 1);
var guts = styleString.substring(start + 1, end).split(',');
 
str = '#';
for (var i = 0; i < 3; i++) {
str += dec2hex[Number(guts[i])];
}
 
if (guts.length == 4 && styleString.substr(3, 1) == 'a') {
alpha = guts[3];
}
} else {
str = styleString;
}
 
return {color: str, alpha: alpha};
}
 
function processLineCap(lineCap) {
switch (lineCap) {
case 'butt':
return 'flat';
case 'round':
return 'round';
case 'square':
default:
return 'square';
}
}
 
/**
* This class implements CanvasRenderingContext2D interface as described by
* the WHATWG.
* @param {HTMLElement} surfaceElement The element that the 2D context should
* be associated with
*/
function CanvasRenderingContext2D_(surfaceElement) {
this.m_ = createMatrixIdentity();
 
this.mStack_ = [];
this.aStack_ = [];
this.currentPath_ = [];
 
// Canvas context properties
this.strokeStyle = '#000';
this.fillStyle = '#000';
 
this.lineWidth = 1;
this.lineJoin = 'miter';
this.lineCap = 'butt';
this.miterLimit = Z * 1;
this.globalAlpha = 1;
this.canvas = surfaceElement;
 
var el = surfaceElement.ownerDocument.createElement('div');
el.style.width = surfaceElement.clientWidth + 'px';
el.style.height = surfaceElement.clientHeight + 'px';
el.style.overflow = 'hidden';
el.style.position = 'absolute';
surfaceElement.appendChild(el);
 
this.element_ = el;
this.arcScaleX_ = 1;
this.arcScaleY_ = 1;
this.lineScale_ = 1;
}
 
var contextPrototype = CanvasRenderingContext2D_.prototype;
contextPrototype.clearRect = function() {
this.element_.innerHTML = '';
};
 
contextPrototype.beginPath = function() {
// TODO: Branch current matrix so that save/restore has no effect
// as per safari docs.
this.currentPath_ = [];
};
 
contextPrototype.moveTo = function(aX, aY) {
var p = this.getCoords_(aX, aY);
this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y});
this.currentX_ = p.x;
this.currentY_ = p.y;
};
 
contextPrototype.lineTo = function(aX, aY) {
var p = this.getCoords_(aX, aY);
this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y});
 
this.currentX_ = p.x;
this.currentY_ = p.y;
};
 
contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,
aCP2x, aCP2y,
aX, aY) {
var p = this.getCoords_(aX, aY);
var cp1 = this.getCoords_(aCP1x, aCP1y);
var cp2 = this.getCoords_(aCP2x, aCP2y);
bezierCurveTo(this, cp1, cp2, p);
};
 
// Helper function that takes the already fixed cordinates.
function bezierCurveTo(self, cp1, cp2, p) {
self.currentPath_.push({
type: 'bezierCurveTo',
cp1x: cp1.x,
cp1y: cp1.y,
cp2x: cp2.x,
cp2y: cp2.y,
x: p.x,
y: p.y
});
self.currentX_ = p.x;
self.currentY_ = p.y;
}
 
contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
// the following is lifted almost directly from
// http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes
 
var cp = this.getCoords_(aCPx, aCPy);
var p = this.getCoords_(aX, aY);
 
var cp1 = {
x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_),
y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_)
};
var cp2 = {
x: cp1.x + (p.x - this.currentX_) / 3.0,
y: cp1.y + (p.y - this.currentY_) / 3.0
};
 
bezierCurveTo(this, cp1, cp2, p);
};
 
contextPrototype.arc = function(aX, aY, aRadius,
aStartAngle, aEndAngle, aClockwise) {
aRadius *= Z;
var arcType = aClockwise ? 'at' : 'wa';
 
var xStart = aX + mc(aStartAngle) * aRadius - Z2;
var yStart = aY + ms(aStartAngle) * aRadius - Z2;
 
var xEnd = aX + mc(aEndAngle) * aRadius - Z2;
var yEnd = aY + ms(aEndAngle) * aRadius - Z2;
 
// IE won't render arches drawn counter clockwise if xStart == xEnd.
if (xStart == xEnd && !aClockwise) {
xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something
// that can be represented in binary
}
 
var p = this.getCoords_(aX, aY);
var pStart = this.getCoords_(xStart, yStart);
var pEnd = this.getCoords_(xEnd, yEnd);
 
this.currentPath_.push({type: arcType,
x: p.x,
y: p.y,
radius: aRadius,
xStart: pStart.x,
yStart: pStart.y,
xEnd: pEnd.x,
yEnd: pEnd.y});
 
};
 
contextPrototype.rect = function(aX, aY, aWidth, aHeight) {
this.moveTo(aX, aY);
this.lineTo(aX + aWidth, aY);
this.lineTo(aX + aWidth, aY + aHeight);
this.lineTo(aX, aY + aHeight);
this.closePath();
};
 
contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {
var oldPath = this.currentPath_;
this.beginPath();
 
this.moveTo(aX, aY);
this.lineTo(aX + aWidth, aY);
this.lineTo(aX + aWidth, aY + aHeight);
this.lineTo(aX, aY + aHeight);
this.closePath();
this.stroke();
 
this.currentPath_ = oldPath;
};
 
contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {
var oldPath = this.currentPath_;
this.beginPath();
 
this.moveTo(aX, aY);
this.lineTo(aX + aWidth, aY);
this.lineTo(aX + aWidth, aY + aHeight);
this.lineTo(aX, aY + aHeight);
this.closePath();
this.fill();
 
this.currentPath_ = oldPath;
};
 
contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
var gradient = new CanvasGradient_('gradient');
gradient.x0_ = aX0;
gradient.y0_ = aY0;
gradient.x1_ = aX1;
gradient.y1_ = aY1;
return gradient;
};
 
contextPrototype.createRadialGradient = function(aX0, aY0, aR0,
aX1, aY1, aR1) {
var gradient = new CanvasGradient_('gradientradial');
gradient.x0_ = aX0;
gradient.y0_ = aY0;
gradient.r0_ = aR0;
gradient.x1_ = aX1;
gradient.y1_ = aY1;
gradient.r1_ = aR1;
return gradient;
};
 
contextPrototype.drawImage = function(image, var_args) {
var dx, dy, dw, dh, sx, sy, sw, sh;
 
// to find the original width we overide the width and height
var oldRuntimeWidth = image.runtimeStyle.width;
var oldRuntimeHeight = image.runtimeStyle.height;
image.runtimeStyle.width = 'auto';
image.runtimeStyle.height = 'auto';
 
// get the original size
var w = image.width;
var h = image.height;
 
// and remove overides
image.runtimeStyle.width = oldRuntimeWidth;
image.runtimeStyle.height = oldRuntimeHeight;
 
if (arguments.length == 3) {
dx = arguments[1];
dy = arguments[2];
sx = sy = 0;
sw = dw = w;
sh = dh = h;
} else if (arguments.length == 5) {
dx = arguments[1];
dy = arguments[2];
dw = arguments[3];
dh = arguments[4];
sx = sy = 0;
sw = w;
sh = h;
} else if (arguments.length == 9) {
sx = arguments[1];
sy = arguments[2];
sw = arguments[3];
sh = arguments[4];
dx = arguments[5];
dy = arguments[6];
dw = arguments[7];
dh = arguments[8];
} else {
throw Error('Invalid number of arguments');
}
 
var d = this.getCoords_(dx, dy);
 
var w2 = sw / 2;
var h2 = sh / 2;
 
var vmlStr = [];
 
var W = 10;
var H = 10;
 
// For some reason that I've now forgotten, using divs didn't work
vmlStr.push(' <g_vml_:group',
' coordsize="', Z * W, ',', Z * H, '"',
' coordorigin="0,0"' ,
' style="width:', W, 'px;height:', H, 'px;position:absolute;');
 
// If filters are necessary (rotation exists), create them
// filters are bog-slow, so only create them if abbsolutely necessary
// The following check doesn't account for skews (which don't exist
// in the canvas spec (yet) anyway.
 
if (this.m_[0][0] != 1 || this.m_[0][1]) {
var filter = [];
 
// Note the 12/21 reversal
filter.push('M11=', this.m_[0][0], ',',
'M12=', this.m_[1][0], ',',
'M21=', this.m_[0][1], ',',
'M22=', this.m_[1][1], ',',
'Dx=', mr(d.x / Z), ',',
'Dy=', mr(d.y / Z), '');
 
// Bounding box calculation (need to minimize displayed area so that
// filters don't waste time on unused pixels.
var max = d;
var c2 = this.getCoords_(dx + dw, dy);
var c3 = this.getCoords_(dx, dy + dh);
var c4 = this.getCoords_(dx + dw, dy + dh);
 
max.x = m.max(max.x, c2.x, c3.x, c4.x);
max.y = m.max(max.y, c2.y, c3.y, c4.y);
 
vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z),
'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(',
filter.join(''), ", sizingmethod='clip');")
} else {
vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;');
}
 
vmlStr.push(' ">' ,
'<g_vml_:image src="', image.src, '"',
' style="width:', Z * dw, 'px;',
' height:', Z * dh, 'px;"',
' cropleft="', sx / w, '"',
' croptop="', sy / h, '"',
' cropright="', (w - sx - sw) / w, '"',
' cropbottom="', (h - sy - sh) / h, '"',
' />',
'</g_vml_:group>');
 
this.element_.insertAdjacentHTML('BeforeEnd',
vmlStr.join(''));
};
 
contextPrototype.stroke = function(aFill) {
var lineStr = [];
var lineOpen = false;
var a = processStyle(aFill ? this.fillStyle : this.strokeStyle);
var color = a.color;
var opacity = a.alpha * this.globalAlpha;
 
var W = 10;
var H = 10;
 
lineStr.push('<g_vml_:shape',
' filled="', !!aFill, '"',
' style="position:absolute;width:', W, 'px;height:', H, 'px;"',
' coordorigin="0 0" coordsize="', Z * W, ' ', Z * H, '"',
' stroked="', !aFill, '"',
' path="');
 
var newSeq = false;
var min = {x: null, y: null};
var max = {x: null, y: null};
 
for (var i = 0; i < this.currentPath_.length; i++) {
var p = this.currentPath_[i];
var c;
 
switch (p.type) {
case 'moveTo':
c = p;
lineStr.push(' m ', mr(p.x), ',', mr(p.y));
break;
case 'lineTo':
lineStr.push(' l ', mr(p.x), ',', mr(p.y));
break;
case 'close':
lineStr.push(' x ');
p = null;
break;
case 'bezierCurveTo':
lineStr.push(' c ',
mr(p.cp1x), ',', mr(p.cp1y), ',',
mr(p.cp2x), ',', mr(p.cp2y), ',',
mr(p.x), ',', mr(p.y));
break;
case 'at':
case 'wa':
lineStr.push(' ', p.type, ' ',
mr(p.x - this.arcScaleX_ * p.radius), ',',
mr(p.y - this.arcScaleY_ * p.radius), ' ',
mr(p.x + this.arcScaleX_ * p.radius), ',',
mr(p.y + this.arcScaleY_ * p.radius), ' ',
mr(p.xStart), ',', mr(p.yStart), ' ',
mr(p.xEnd), ',', mr(p.yEnd));
break;
}
 
 
// TODO: Following is broken for curves due to
// move to proper paths.
 
// Figure out dimensions so we can do gradient fills
// properly
if (p) {
if (min.x == null || p.x < min.x) {
min.x = p.x;
}
if (max.x == null || p.x > max.x) {
max.x = p.x;
}
if (min.y == null || p.y < min.y) {
min.y = p.y;
}
if (max.y == null || p.y > max.y) {
max.y = p.y;
}
}
}
lineStr.push(' ">');
 
if (!aFill) {
var lineWidth = this.lineScale_ * this.lineWidth;
 
// VML cannot correctly render a line if the width is less than 1px.
// In that case, we dilute the color to make the line look thinner.
if (lineWidth < 1) {
opacity *= lineWidth;
}
 
lineStr.push(
'<g_vml_:stroke',
' opacity="', opacity, '"',
' joinstyle="', this.lineJoin, '"',
' miterlimit="', this.miterLimit, '"',
' endcap="', processLineCap(this.lineCap), '"',
' weight="', lineWidth, 'px"',
' color="', color, '" />'
);
} else if (typeof this.fillStyle == 'object') {
var fillStyle = this.fillStyle;
var angle = 0;
var focus = {x: 0, y: 0};
 
// additional offset
var shift = 0;
// scale factor for offset
var expansion = 1;
 
if (fillStyle.type_ == 'gradient') {
var x0 = fillStyle.x0_ / this.arcScaleX_;
var y0 = fillStyle.y0_ / this.arcScaleY_;
var x1 = fillStyle.x1_ / this.arcScaleX_;
var y1 = fillStyle.y1_ / this.arcScaleY_;
var p0 = this.getCoords_(x0, y0);
var p1 = this.getCoords_(x1, y1);
var dx = p1.x - p0.x;
var dy = p1.y - p0.y;
angle = Math.atan2(dx, dy) * 180 / Math.PI;
 
// The angle should be a non-negative number.
if (angle < 0) {
angle += 360;
}
 
// Very small angles produce an unexpected result because they are
// converted to a scientific notation string.
if (angle < 1e-6) {
angle = 0;
}
} else {
var p0 = this.getCoords_(fillStyle.x0_, fillStyle.y0_);
var width = max.x - min.x;
var height = max.y - min.y;
focus = {
x: (p0.x - min.x) / width,
y: (p0.y - min.y) / height
};
 
width /= this.arcScaleX_ * Z;
height /= this.arcScaleY_ * Z;
var dimension = m.max(width, height);
shift = 2 * fillStyle.r0_ / dimension;
expansion = 2 * fillStyle.r1_ / dimension - shift;
}
 
// We need to sort the color stops in ascending order by offset,
// otherwise IE won't interpret it correctly.
var stops = fillStyle.colors_;
stops.sort(function(cs1, cs2) {
return cs1.offset - cs2.offset;
});
 
var length = stops.length;
var color1 = stops[0].color;
var color2 = stops[length - 1].color;
var opacity1 = stops[0].alpha * this.globalAlpha;
var opacity2 = stops[length - 1].alpha * this.globalAlpha;
 
var colors = [];
for (var i = 0; i < length; i++) {
var stop = stops[i];
colors.push(stop.offset * expansion + shift + ' ' + stop.color);
}
 
// When colors attribute is used, the meanings of opacity and o:opacity2
// are reversed.
lineStr.push('<g_vml_:fill type="', fillStyle.type_, '"',
' method="none" focus="100%"',
' color="', color1, '"',
' color2="', color2, '"',
' colors="', colors.join(','), '"',
' opacity="', opacity2, '"',
' g_o_:opacity2="', opacity1, '"',
' angle="', angle, '"',
' focusposition="', focus.x, ',', focus.y, '" />');
} else {
lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity,
'" />');
}
 
lineStr.push('</g_vml_:shape>');
 
this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
};
 
contextPrototype.fill = function() {
this.stroke(true);
}
 
contextPrototype.closePath = function() {
this.currentPath_.push({type: 'close'});
};
 
/**
* @private
*/
contextPrototype.getCoords_ = function(aX, aY) {
var m = this.m_;
return {
x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2,
y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2
}
};
 
contextPrototype.save = function() {
var o = {};
copyState(this, o);
this.aStack_.push(o);
this.mStack_.push(this.m_);
this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);
};
 
contextPrototype.restore = function() {
copyState(this.aStack_.pop(), this);
this.m_ = this.mStack_.pop();
};
 
function matrixIsFinite(m) {
for (var j = 0; j < 3; j++) {
for (var k = 0; k < 2; k++) {
if (!isFinite(m[j][k]) || isNaN(m[j][k])) {
return false;
}
}
}
return true;
}
 
function setM(ctx, m, updateLineScale) {
if (!matrixIsFinite(m)) {
return;
}
ctx.m_ = m;
 
if (updateLineScale) {
// Get the line scale.
// Determinant of this.m_ means how much the area is enlarged by the
// transformation. So its square root can be used as a scale factor
// for width.
var det = m[0][0] * m[1][1] - m[0][1] * m[1][0];
ctx.lineScale_ = sqrt(abs(det));
}
}
 
contextPrototype.translate = function(aX, aY) {
var m1 = [
[1, 0, 0],
[0, 1, 0],
[aX, aY, 1]
];
 
setM(this, matrixMultiply(m1, this.m_), false);
};
 
contextPrototype.rotate = function(aRot) {
var c = mc(aRot);
var s = ms(aRot);
 
var m1 = [
[c, s, 0],
[-s, c, 0],
[0, 0, 1]
];
 
setM(this, matrixMultiply(m1, this.m_), false);
};
 
contextPrototype.scale = function(aX, aY) {
this.arcScaleX_ *= aX;
this.arcScaleY_ *= aY;
var m1 = [
[aX, 0, 0],
[0, aY, 0],
[0, 0, 1]
];
 
setM(this, matrixMultiply(m1, this.m_), true);
};
 
contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) {
var m1 = [
[m11, m12, 0],
[m21, m22, 0],
[dx, dy, 1]
];
 
setM(this, matrixMultiply(m1, this.m_), true);
};
 
contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) {
var m = [
[m11, m12, 0],
[m21, m22, 0],
[dx, dy, 1]
];
 
setM(this, m, true);
};
 
/******** STUBS ********/
contextPrototype.clip = function() {
// TODO: Implement
};
 
contextPrototype.arcTo = function() {
// TODO: Implement
};
 
contextPrototype.createPattern = function() {
return new CanvasPattern_;
};
 
// Gradient / Pattern Stubs
function CanvasGradient_(aType) {
this.type_ = aType;
this.x0_ = 0;
this.y0_ = 0;
this.r0_ = 0;
this.x1_ = 0;
this.y1_ = 0;
this.r1_ = 0;
this.colors_ = [];
}
 
CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {
aColor = processStyle(aColor);
this.colors_.push({offset: aOffset,
color: aColor.color,
alpha: aColor.alpha});
};
 
function CanvasPattern_() {}
 
// set up externs
G_vmlCanvasManager = G_vmlCanvasManager_;
CanvasRenderingContext2D = CanvasRenderingContext2D_;
CanvasGradient = CanvasGradient_;
CanvasPattern = CanvasPattern_;
 
})();
 
} // if
/trunk/plugins/ipfm/dygraph/update-dygraph.sh
0,0 → 1,5
#!/bin/sh
wget http://dygraphs.com/excanvas.js
rm excanvas.js.*
wget http://dygraphs.com/dygraph-combined.js
rm dygraph-combined.js.*
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/ipfm/icinga2.conf
0,0 → 1,46
// Put this file in /etc/icinga2/conf.d/...
 
// VNag - Nagios Framework for PHP
// Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
// Licensed under the terms of the Apache 2.0 license
//
// Revision 2018-07-15
 
object CheckCommand "vnag_ipfm" {
command = [ "/daten/vnag/plugins/ipfm/check_ipfm" ]
 
arguments = {
"-w" = {
value = "$vnag_ipfm_currentWarn$,$vnag_ipfm_expectedWarn$"
description = "<currentTraffic>GB,<expectedTraffic>GB (Warning range)"
}
"-c" = {
value = "$vnag_ipfm_currentCrit$,$vnag_ipfm_expectedCrit$"
description = "<currentTraffic>GB,<expectedTraffic>GB (Critical range)"
}
"-l" = {
value = "$vnag_ipfm_limit$"
description = "The monthly limit of your provider (just for optical measurement)"
}
"-L" = {
value = "$vnag_ipfm_logDir$"
description = "Directory of the ipfm log files (default /var/log/ipfm)"
}
}
}
 
// Example usage:
//
// apply Service "example_eth0_ipfm" {
// import "generic-service"
// check_command = "vnag_ipfm"
// vars = {
// vnag_ipfm_currentWarn = "6TB"
// vnag_ipfm_currentCrit = "8TB"
// vnag_ipfm_expectedWarn = "8TB"
// vnag_ipfm_expectedCrit = "15TB"
// vnag_ipfm_limit = "10TB"
// vnag_ipfm_logDir = "/var/log/ipfm"
// }
// assign where host.name == NodeName
// }
/trunk/plugins/ipfm/index.php
0,0 → 1,63
<?php /* <ViaThinkSoftSignature>cI1s2a3mT+MdTE7/qLxngIG1+5QjriFFNzaY7TpgSXizwFFodagYOOls59lMWI8A3S6h2OfgqP4Bxc5FISEhEj+Ry86HfMDROJuVwjUPlEF8sJX50f0t5aAbA6do23tq1USmXJZmeDF8GEWXu/evWQOXEvTZs6lLKEnYZVcT1G48fHosKIX8bB6rSlJ2dtblxUeFVd3u91TUiqWym3T2k/U8S9/dbrB0KWQf18BJeai+08R8rY8s5/oOuL0KJAimdUCECOlPvOH+QMxPShNEhmMTebJsnHZJYyJN6uDre0nDvqW8g+F3SfbwudblG8+7ng0spQRtoa0rLhEON2H68Wd81UUIRd+Ypx5GzwPaCKFMJ0vKQGtN2fqUa8okw/ssOtO8o449euHaC4QDRkZpMfO25EZvT0syL/aSaiSqpsadUJ8PF38CpOWenTGimaER3vUJf1aA2X/QCNlun6BxL+cb2rTHfgvtjD02W4xyZebAiRIY5n7RkMds/7OVizPiwqU9AcO4XNlTGJ6nqlmDzSPj0dYQDZrfYxsh08ahucmG45qNRJwiK1yf2pMoSVsuCoi4orOehMinxcoKW2uTUddXmcIfxL1UN2TO2cZ4m3dWq4D6/aQSnsPH7sZ4UbQ9RCSF+zuQRvUgxxa2A1mRK3eJOhA2Ne/dYSpsG5dxE7rqLNo1rc5BQw9mOF2fWlfjvwp8vtab0xO/XWukOcaX+rwAQ7nQcugfnxgZRpo7aghvysheDPHue81g4E1NuoiiakguHtg2uyThBCUWwUsvTkuvXTnK1hCpfB9lTYDu8fi4BzTXNhunCIyQpTVMcox7vkxaMe3dYKqmI1P8nmRiivQuZNO8lzFxB3nuLLrVx3b2EnOOAEcpmtXF0ir1iWHSV90DiP/4VhBH8phrKHT66FJmHdGwy18/yPjmNQWp02E7uz/sSoK1peKxsK3FJ1sfUsWAny1DFN8bxN6qpuJvDwF9mJ+H7Szir8JJF/Bt+xBdm68qvEvJpahhfK87FWR8r52nl5kBDveXD167KyuYA/YHlJQnzQcqD3488YUbecRXNojN+x2UVAyZmAcANDejPWdsK0LVXwAZoFKTZ0CUzzZGdFPA+GqeSz3zx+2CpFb2b+7akGuEcRAozWCemeuPd2JGu7r8jA1iTShEGru7X11aBIyRHd/crpijEEyGLdCOZ2prRf5E4Vd+cMOMsuu7di6jvEvp+ttNJTMJ9N+0RnIp+k8h0Z6a1pqT1/t+OYNPCeeSgimtlj6/JktSVDASjKUY2wyQxKTsHez2R9khCrsz+PMroJCp5lSbQLKoUMIlrtVgwWbohnJeN1ag1RlyizLl62l8tP2c7SyWJlL8ag==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-19
*/
 
// This file (index.php) is intended to be called by your browser.
// If you want to access via Nagios/Icinga or CLI, call "check_ipfm".
 
declare(ticks=1);
 
define('USE_DYGRAPH', false); // Slow!
define('ALLOW_HTTP_PARAMTER_OVERWRITE', false); // true: Allow the user to set their own ?w=...&c=... etc.
 
if (!ALLOW_HTTP_PARAMTER_OVERWRITE) {
$_REQUEST['L'] = '/var/log/ipfm';
$_REQUEST['l'] = '10TB'; // LeaseWeb gives us 10 TB free traffic
$_REQUEST['w'] = '6TB,8TB';
$_REQUEST['c'] = '8TB,15TB';
}
 
?><!DOCTYPE HTML>
 
<html>
 
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="refresh" content="300; URL=<?php echo isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : ''; ?>">
<title>Traffic monitor</title>
<?php if (USE_DYGRAPH) { ?>
<!--[if IE]>
<script type="text/javascript" src="excanvas.js"></script>
<![endif]-->
<script type="text/javascript" src="dygraph/dygraph-combined.js"></script>
<?php } ?>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<meta name="robots" content="noindex">
</head>
 
<body>
 
<h1>Traffic monitor</h1>
 
<?php
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__ . '/IpFlowMonitorCheck.class.php';
 
$job = new IpFlowMonitorCheck();
$job->http_visual_output = VNag::OUTPUT_EXCEPTION;
$job->http_invisible_output = VNag::OUTPUT_ALWAYS;
$job->run();
unset($job);
 
?>
</body>
 
</html>
/trunk/plugins/joomla_version/JoomlaVersionCheck.class.php
0,0 → 1,105
<?php /* <ViaThinkSoftSignature>FiyjR9oqgAeei220CERRBiLHuRAHb0/kx6b9OY4Ltv2b0fJO25aP3K18k/KQntpXh28Yw3g1W/w807lr4xgRILQhhA3/JejkqNlKMb5bTZMcaNbTxBD44K/AHHXE62HesAYgtFyG0j8qRn+MpTEBktuwxUmMqU1HT+SHQYq9Ytj0jVX4o0hbZ29yv23waZUYI7q5as5ROs4veCrjPDSlVRty/jjviFe9ercdIta/ihXGfTR4MNymXCLKO3c3Y52yVBcIN0xd0D3YvWZb1eyjMT1akpnFWfg+2RSqkwtNJUGHmiTF9m54dE3OfQGLEQhx062oYWkbB7/Mc1sSs/U7eBdN553UycFI6j+M5yXhKmcAFTb3RMdiNRL5RsWYkx6u/tvJxOCmJZ8Ln41pqdJiXSjE52psHLNcVlOAwzKdjqsC8l4kpYBQJhVMaIkfAiJ8t5lKkYjT73QpaJl2db2Z95Skk8Utp+apI2jK/1x6IGE+PXUAIP7luQLPBrSaOrcCRRr1gXzXWJJNpDuWMVIfsFqaLblSMcRwEKz8fRHM3Z/fiRKHW4Zo5eBmoq5kqafSHmZnA3jVyQkIuqYa7nrwLpmsVT1rHqKWYbj7NduStIm0MNwdkui2AWZsA0G/NsXx08IrZlJ8Cd3U0pZ1QGbGrOSfyWzLZh6oGCHnbHFgAIz5x6uWrwLpxXhuTDVws+oiSA02YdC8Flbew71AQKkqVsV0U6hQYFsHsL+pvu04TcqP05xfwBZl3UWtRPuSg5pio5vOdtGIVFa3m3D01fQ9F4iRSZJCCMLcndD5F94CSCimd3zUyjNU9fMYaZ1Z9NE7HEt4tzhM7M0wD/ea3HhG1cjNfulUFvy+04x0YuS7cIT/zCiDFkAB4T+hWwgbPBIJHumVCVbVhQr8glc+RGWMIrQ1BfHIsxOdnGxrW/jxMpcqzjO9nNB0QDsMSNaAuXQ8EVOMnDmiH8daaQMQH2QBKXtgcKPVPJpqSbvPT2WGEAgdlfDphFhOC/L18dt5Ja8KGbBtQ2dhL6FLoPmcWPY9jFrxv+eSICvUi5Wc6okClao/ml2xPis+O+kRbve1r6PkfKFhnG3hCQ+jxyO1MRM4D+oEOAP/Xbl4/Uc+u5Ot1sbFGs4VoiKibPeiggIizzfp05R+tMgMIz7hUmAM6YFkZzxzKThl8V3s4yXLGv/drBJpSa1fG4lZmmOXfCvsAf15J660ObOxn7AiJN8fT4EfLjHgoTZiCFYU2UMFwXpfKedm7u6+0gLyFk6ni4C6DAlUKKEVK5Cm+p/Ql3cNr70mUhimfsrB26EYkwFWcfQGWhkUs1F5fmglVC1TSn9MflBEO0hUH2e/ivQIdNssN7Ni1w==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
// TODO: Also check extensions
 
declare(ticks=1);
 
class JoomlaVersionCheck extends VNag {
protected $argSystemDir = null;
 
public function __construct() {
parent::__construct();
 
$this->registerExpectedStandardArguments('Vht');
 
$this->getHelpManager()->setPluginName('check_joomla_version');
$this->getHelpManager()->setVersion('1.0');
$this->getHelpManager()->setShortDescription('This plugin checks if a local Joomla system has the latest version installed.');
$this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
$this->getHelpManager()->setSyntax('$SCRIPTNAME$ [-d <directory>]');
$this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
 
// Individual (non-standard) arguments:
$this->addExpectedArgument($this->argSystemDir = new VNagArgument('d', 'directory', VNagArgument::VALUE_REQUIRED, 'joomlaPath', 'The local directory where your Joomla installation is located.'));
}
 
protected function check_joomla_system($path) {
$path = realpath($path) === false ? $path : realpath($path);
 
$manifest_file = $path.'/administrator/manifests/files/joomla.xml';
 
if (!file_exists($manifest_file)) {
throw new Exception("Manifest file $manifest_file not found");
}
 
$cont = file_get_contents($manifest_file);
$manifest = new SimpleXMLElement($cont);
 
$version = (string)$manifest->version;
 
$count = 0;
foreach ($manifest->updateservers->server as $updateserver) {
$cont = @file_get_contents($updateserver);
if ($cont) {
$extensions = new SimpleXMLElement($cont);
foreach ($extensions as $candidate) {
$count++;
if ($version == (string)$candidate['version']) {
$detailsurl = (string)$candidate['detailsurl'];
if ($detailsurl == 'https://update.joomla.org/core/extension.xml') $type = 1;
else if ($detailsurl == 'https://update.joomla.org/core/sts/extension_sts.xml') $type = 2;
else $type == 0;
return array($type, $version);
}
}
}
}
 
if ($count == 0) {
throw new Exception("Error checking update servers");
}
 
return array(-1, $version);
}
 
protected function cbRun($optional_args=array()) {
$system_dir = $this->argSystemDir->getValue();
if (empty($system_dir)) {
throw new Exception("Please specify the directory of the Joomla installation.");
}
$system_dir = realpath($system_dir) === false ? $system_dir : realpath($system_dir);
 
if (!is_dir($system_dir)) {
throw new Exception('Directory "'.$system_dir.'" not found.', false);
}
 
list($type, $version) = $this->check_joomla_system($system_dir);
 
if ($type == 1) {
$this->setStatus(VNag::STATUS_OK);
$this->setHeadline("Version $version (Long-Term-Support) found at $system_dir", true);
} else if ($type == 2) {
$this->setStatus(VNag::STATUS_OK);
$this->setHeadline("Version $version (Short-Term-Support) found at $system_dir", true);
} else if ($type == 0) {
// This should not happen
$this->setStatus(VNag::STATUS_OK);
$this->setHeadline("Version $version (supported) found at $system_dir", true);
} else if ($type == -1) {
$this->setStatus(VNag::STATUS_WARNING);
$this->setHeadline("Version $version is outdated at $system_dir", true);
} else {
assert(false);
}
}
}
 
/trunk/plugins/joomla_version/check_joomla_version
0,0 → 1,20
#!/usr/bin/php
<?php /* <ViaThinkSoftSignature>fWU2TFVRhDYFd3cF/gMFUU9vqavaPZVcyhrw4QyATK9E03WL4RAfM3y0KejlZBC3kmkzfCwFpeukjCIfOCkYXydURpnGCn5V+BqGmcvXp5VdQOHufjHjCrLskD5HMmghWYN/iSVbCVdp3S9vXwIMyj9FIHv0FDeRkCS+AVaRuHhus3P64ZkOodm8pxxyCBblYuoLGASFf8fh+pIuWSKRsItn+SVU0nHuvlT2/GQi7E1vl1zHoubUn49/9tOKQWLa0YPAj8CDPkbqvqL5e1evJnoqvULMX8HSAlf1YCAfABw8Z7LVQU09IDSGjMZ8WyIxRibGOlXZZZR+uZQQEMi0LDUxR1/QK1FBNdkhAjD/P1hXsabScP55CiNSJOOH3nQD2eCIaxdHuzSc+kYW019IcPIkDLsJxgaZtZs6ySWTJ42c54qFsheVBm9CaPMlguq4WIh6vMuAlkRtvLxaOLeDjhr57W3Z6Zn3mKsRnyLW8NgCnEg7yMfM6p29aiOfrxLmfiwfq4KWlOBpr563fru+sBSs3OGKbA3h7ca8pnzlseWI2ld+3sp7cjHBZTO07phVTz2imqMPE2Rt32jIxE5wIeUzU+UxcjrFfAxxdLzhjXZ8RCWiWfgdXV8yMbuIdy8vzJAKaO/f3g+RC96e9/LKjEGyaDyyVPT2HEBZrvvnGeiT1PVMqdKa+YG6xs4m/jiq53yvUUCk05t+qSi+9xz64qHCOBIkUKHhbb9doNc68Vw0Vt89QOCx2Zl/BOgQCWJ7lshCqlEjqTWQ3cy6Mcg1197H0RMUJPz1ki2CRQi1B0UKf/WTs9VUXngcDxFGbS35dFFl02cRfPSEPVb9kvB7Y9CBEmEtnHr8Ogr78vZrUy+69AnyV0S+ny8nisYP6QzSBOLkR/Dd7dcq14EvmNnMd1C8VaFULNd7Bo9FHYo+46O+GBgRS9iE2af+nZBL9bpYfYLv9tCQMb3w2wAdJR0bjlIMxL6LGduQhD7QUwVbJYJuE0+vIsnAYZyzGstEFpozfdESn3Grcc4q2FtFkSyEh/JRZZlsCXONzEwNjblnJigLYfJ3pBVrRMY9BERGhhyoHT/Q6yNIkNuJpBnQbfJx9RvDtyr7lIdZ6I0xtxEZ1NrQQoyp9w0GaDwagfOqzXM8UOqdIEZhDVdR9ZbC2Ty76ohuAL3qOFfFToxPkVJ5YvXthXs51GjfJi8KpQCb12XxN8WC8qJHT4Y7ElEZadlLvxl/a/k5kWgdcGaPtBaoTgLDF3jjm2wN1GF3hHhX0BkGuLGFzbeLDxvGRdB9h+eaaAH+5cewEVNVXcLbSaEah/p1Zw0iw4XNyU+WgK1dKWH16mZLWrsYc5XpoTszIpmDsw==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__ . '/JoomlaVersionCheck.class.php';
 
$job = new JoomlaVersionCheck();
$job->run();
unset($job);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/joomla_version/icinga2.conf
0,0 → 1,48
// Put this file in /etc/icinga2/conf.d/...
 
// VNag - Nagios Framework for PHP
// Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
// Licensed under the terms of the Apache 2.0 license
//
// Revision 2018-07-15
 
object CheckCommand "vnag_joomla_version" {
command = [ "/daten/vnag/plugins/joomla_version/check_joomla_version" ]
 
arguments = {
"-d" = {
value = "$vnag_joomla_version_dir$"
description = "Location where the Joomla installation is located"
required = true
}
}
}
 
// Example usage:
//
// apply Service "example_website1_joomla_version" {
// import "generic-service"
// check_command = "vnag_joomla_version"
// vars = {
// vnag_joomla_version_dir = "/var/www/website1/joomla/"
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_website2_joomla_version" {
// import "generic-service"
// check_command = "vnag_joomla_version"
// vars = {
// vnag_joomla_version_dir = "/var/www/website2/joomla/"
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_website3_joomla_version" {
// import "generic-service"
// check_command = "vnag_joomla_version"
// vars = {
// vnag_joomla_version_dir = "/var/www/website3/joomla/"
// }
// assign where host.name == NodeName
// }
/trunk/plugins/last/LastCheck.class.php
0,0 → 1,210
<?php /* <ViaThinkSoftSignature>akRkqMquPkfxpwy3lnAlcQ1qVAUdTJBHZNOG+o13yNrgyHRqadEskkSxmItifQzCENCOBCXf4QUqo8xtFT0uxyzv/R0ZrB8H0dF+2LslQ6eYj+IrPgbiQoFY4FoxAS24ZCpH8v+GYD4lq/UmU+c7eggeNGtv9ZYkQaz2ZUS4hT0nrP7qO2quF1dpm+8dsB5pKj9iY/ujHP9iEWzn3d8BhgkaSed+GBkqurqY1lc+2l2tCsT1ZPEOR41uWLeSya1WGwEAWy6/2ih4x5dG3lsNgKRcJyDdcDYw+mhXq3vxPeqcMWFiplq6cF9XxxY3NHOk6HcIO7qR52jOkU7Kvy31CPso0C12h0xFgo9fvj3BJUJWZvSw00I1SqRMJn2o2+KtVCWSfMGJ5brgRCMNdHDiCCbkFaRtElsv1q0ewTLotrRohZxJpRwoOK7dEDsR+V0hhOfYzZ/zRaNqG/LPIqSeBsZhA7km8IpZlwSbUom2PKKWdL8YBwSdqjtgM9Z3B0TQDkhSvU17mICuIgjQfeMwxyaUHFYvA+yqofcy9g2GQHTj15B2s39gnW9pKgVK35lRKOCoQ6rYptBfHUXH02VjSLqcFgoV7cOamBftfC55+RRpvfZURQUvgWbBIYtQ3HDeze775vdbr85HL6ADKA2Rdd/HSG1E+GMuXUokcWOxg80ih+HnnrGqfFcohmfs1qy6ZZtYQBnJszFZATsMF+AdztxJahbVf7lrM36Zl22kXpkz8lX2lp382bBvBBYwWUaf3j+UBLWHoFfnOjc1BnxECvuAIlgiD7mRIYIx/WQxlF1MU3ByrVuIzfOR2j3Xy+Iv0ettCVNSQdCnN+B2WV/Hqtj1qLsXgZcxdYatlqDKLytyk2bSyX/WLnRj5xnjWEGDPAoblIjknHz9BiDWRYNdSqZ1skixKIZTbynhqWrG9dKSPvDfdXpvguRB6tSWK3/70aOfWf3TnmTBHXS3/NvGzV+3WtZfujCXTxBSCuV6ReTIuqUbKoVT/rCX5sMNMDuElsbHjg031VKNyqjx3L9F/fMopue8G1vu2QCsjiGU59EwtakcrobMyopZwV8eqe3/By7SjVVL11MquTEV+qIWV3gNtlFFroCO+ztVdKj1+FMsZtZfDhHkxeHG/sx64CW7B1mw5pPCr3FriDScWy3XfD29ah1Tx0/6AsHMViLNCMK65bP5ttp7BBb2vnGX68vc9qMNCBCIhR9lOwPobtzB4MpVAHX6dEn/3XVhkoW7O7jcz3CkgZOZJv8ymKE4SUw7s/ns6w/m4wyujDdp9343WuALsxrxXMswqiTx7v1hmeJccT9dRMJYGQ7DRnB8Z1K+px6FALfwMg7OMcbQh+wiwg==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-11-03
*
* Changelog:
* 2018-08-01 1.0 Initial release
* 2018-09-02 1.1 Added argument -e|--emptyok
* Output a warning if the Linux user does not exist.
* 2018-10-01 1.2 Fixed a bug where too many unnecessary requests were sent to ipinfo.io
* Cache file location ~/.last_ipcache is now preferred
* A token for ipinfo.io can now be provided
* 2018-11-03 1.2.1 "system boot" lines are now excluded
*/
 
// QUE: should we allow usernames to have wildcards, regexes or comma separated?
 
declare(ticks=1);
 
class LastCheck extends VNag {
private $argUser = null;
private $argRegex = null;
private $argWtmpFiles = null;
private $argEmptyOk = null;
private $argIpInfoToken = null;
 
private $cache = null;
private $cacheFile = null;
private $cacheDirty = false;
 
protected function getIpCacheFile() {
$homedir = @getenv('HOME');
if ($homedir) {
$try = "${homedir}/.last_ipcache";
if (file_exists($try)) return $try;
if (@touch($try)) return $try;
}
 
$user = posix_getpwuid(posix_geteuid());
if (isset($user['dir'])) {
$homedir = $user['dir'];
$try = "${homedir}/.last_ipcache";
if (file_exists($try)) return $try;
if (@touch($try)) return $try;
}
 
if (isset($user['name'])) {
$username = $user['name'];
$try = "/tmp/ipcache_${username}.tmp";
if (file_exists($try)) return $try;
if (@touch($try)) return $try;
}
 
return false; // should usually never happen
}
 
public function __construct() {
parent::__construct();
 
if ($this->is_http_mode()) {
// Don't allow the standard arguments via $_REQUEST
$this->registerExpectedStandardArguments('');
} else {
$this->registerExpectedStandardArguments('Vhtv');
}
 
$this->addExpectedArgument($this->argUser = new VNagArgument('u', 'user', VNagArgument::VALUE_REQUIRED, 'user', 'The Linux username. If the argument is missing, all users will be checked.', null));
$this->addExpectedArgument($this->argRegex = new VNagArgument('R', 'regex', VNagArgument::VALUE_REQUIRED, 'regex', 'The regular expression (in PHP: preg_match) which is applied on IP, Hostname, Country, AS number or ISP name. If the regular expression matches, the login will be accepted, otherweise an alert will be triggered. Example: /DE/ismU or /Telekom/ismU', null));
$this->addExpectedArgument($this->argWtmpFiles = new VNagArgument('f', 'wtmpfile', VNagArgument::VALUE_REQUIRED, 'wtmpfile', 'Filemask of the wtmp file (important if you use logrotate), e.g. \'/var/log/wtmp*\'', '/var/log/wtmp*'));
$this->addExpectedArgument($this->argEmptyOk = new VNagArgument('e', 'emptyok', VNagArgument::VALUE_FORBIDDEN, null, 'Treat an empty result (e.g. empty wtmp file after rotation) as success; otherwise treat it as status "Unknown"', null));
$this->addExpectedArgument($this->argIpInfoToken = new VNagArgument(null, 'ipInfoToken', VNagArgument::VALUE_REQUIRED, 'token', 'If you have a token for ipinfo.io, please enter it here. Without token, you can query the service approx 1,000 times per day (which should be enough)', null));
 
$this->getHelpManager()->setPluginName('vnag_last');
$this->getHelpManager()->setVersion('1.2');
$this->getHelpManager()->setShortDescription('This plugin checks the logs of the tool "LAST" an warns when users have logged in with an unexpected IP/Country/ISP.');
$this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
$this->getHelpManager()->setSyntax('$SCRIPTNAME$ [-v] [-e] [-u username] [-R regex] [--ipInfoToken token]');
$this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
 
$this->cacheFile = $this->getIpCacheFile();
$this->cache = $this->cacheFile ? json_decode(file_get_contents($this->cacheFile),true) : array();
}
 
public function __destruct() {
if ($this->cacheFile && $this->cacheDirty) {
@file_put_contents($this->cacheFile, json_encode($this->cache));
}
}
 
private function getCountryAndOrg($ip) {
if (isset($this->cache[$ip])) return $this->cache[$ip];
 
$url = 'https://ipinfo.io/'.urlencode($ip).'/json';
$token = $this->argIpInfoToken->getValue();
if ($token) $url .= '?token='.urlencode($token);
 
// fwrite(STDERR, "Note: Will query $url\n");
$cont = file_get_contents($url);
if (!$cont) return array();
if (!($data = @json_decode($cont, true))) return array();
if (isset($data['error'])) return array();
 
if (isset($data['bogon']) && ($data['bogon'])) {
// Things like 127.0.0.1 do not belong to anyone
$res = array();
} else {
$res = array();
if (isset($data['hostname'])) $res[] = $data['hostname'];
if (isset($data['country'])) $res[] = $data['country'];
list($as, $orgName) = explode(' ', $data['org'], 2);
$res[] = $as;
$res[] = $orgName;
}
 
$this->cache[$ip] = $res;
$this->cacheDirty = true;
return $res;
}
 
private function getLastLoginIPs($username) {
$cont = '';
$files = glob($this->argWtmpFiles->getValue());
foreach ($files as $file) {
if (trim($username) == '') {
$cont .= shell_exec('last -f '.escapeshellarg($file).' -F -w '); // all users
} else {
$cont .= shell_exec('last -f '.escapeshellarg($file).' -F -w '.escapeshellarg($username));
}
}
preg_match_all('@^(\S+)\s+(\S+)\s+(\S+)\s+(.+)$@ismU', $cont, $m, PREG_SET_ORDER);
foreach ($m as $key => &$a) {
if (($a[2] === 'system') && ($a[3] === 'boot')) {
// reboot system boot 4.9.0-8-amd64 Fri Oct 12 02:10 still running
unset($m[$key]);
} else if ($a[2] === 'begins') {
// wtmp.1 begins Fri Oct 12 02:10:43 2018
unset($m[$key]);
} else {
array_shift($a);
}
}
return $m;
}
 
protected function cbRun() {
if (!`which which`) {
throw new VNagException("Program 'which' is not installed on your system");
}
 
if (!`which last`) {
throw new VNagException("Program 'last' (usually included in package smartmontools) is not installed on your system");
}
 
$username = $this->argUser->available() ? $this->argUser->getValue() : '';
$regex = $this->argRegex->available() ? $this->argRegex->getValue() : null;
 
if (($username != '') && function_exists('posix_getpwnam') && !posix_getpwnam($username)) {
$this->setStatus(VNag::STATUS_WARNING);
$this->addVerboseMessage("WARNING: Currently, there is no Linux user with name '$username'.", VNag::VERBOSITY_SUMMARY);
}
 
$count_total = 0;
$count_ok = 0;
$count_warning = 0;
 
foreach ($this->getLastLoginIPs($username) as list($username, $pts, $ip, $times)) {
$count_total++;
 
$fields = $this->getCountryAndOrg($ip);
$fields[] = $ip;
 
if (is_null($regex)) {
// No regex. Just show the logins for information (status stays VNag::STATUS_UNKNOWN)
$this->addVerboseMessage("INFO: ".implode(' ',$fields)." @ $username, $pts $times", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
} else {
$match = false;
foreach ($fields as $f) {
if (preg_match($regex, $f, $dummy)) {
$match = true;
break;
}
}
 
if ($match) {
$count_ok++;
$this->addVerboseMessage("OK: ".implode(' ',$fields)." @ $username $pts $times", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
$this->setStatus(VNag::STATUS_OK);
} else {
$count_warning++;
$this->addVerboseMessage("WARNING: ".implode(' ',$fields)." @ $username $pts $times", VNag::VERBOSITY_SUMMARY);
$this->setStatus(VNag::STATUS_WARNING);
}
}
}
 
if (is_null($regex)) {
$this->setHeadline("Checked $count_total logins (No checks done because argument 'Regex' is missing)");
} else {
if (($count_total == 0) && ($this->argEmptyOk->count() > 0)) {
$this->setStatus(VNag::STATUS_OK);
}
$this->setHeadline("Checked $count_total logins ($count_ok OK, $count_warning Warning)");
}
}
}
/trunk/plugins/last/check_last
0,0 → 1,20
#!/usr/bin/php
<?php /* <ViaThinkSoftSignature>EAT0dg6XVATJb1tgON94YJYkJyKfAOJFSF3tKEvz7Uq7QgpJqzw44pe2PsGsMJeRYYYeb7J9n2Xk+RHkrdnXY7JWUn/AZVdXmnCLFw4kSW7H1tMQUQUVpiHIIJXJ5hWSk243Hk5KjpfvbG42chfo9vhRYPbDqJD4o7I4q7F/rJKkxRF2OArKOuAjTTURSAxSHWUuK34rx30M/lCYCpRQ0y4o22zz/5BJw1Y2MdNfFD4CsjcfMElssE95/5djI4EGkbeZKtFKlM2BfR5CEyyG15fvgUD9xPdqUSm+oHshOTekiY02vodgxGY+tWCboxZlNVNp7Cpb4vy3tyEj6lJemzjHbcrIksdYAoT1YlttLIFhyYdczlZhBjkHKJze4JtxKG2t6WkG0DwRY3HLDquTuhQs0KXTzmbsJJ/IkL43GfWFHu9jywi98aRs3KeSkaQJ7nXlgAm0FUGlf6dsuQxLm3jHZ5V4pLX5s4MQocIVH8XDs9+JcCqQWZ22CitIGkiJFglh8wp2+PiAIm0oFmN9fTd8RlwP0foS/AecsuffpiPrJzWMtTkJ7jTQV4CT5tKkcdDFZqOFxEDGCWw/wCYLO5hrGnuQOiSGNJIH8sVWNN8GxNNL1yjwd2Odr4C9qybkhq1vubsq9ClsaFuAVNjdOPKFCPJl65w+zeGJl3xglXnGkpqim6NRhywllvUrPbENdC6kXGlxim/J0LIA5Rv/OBYyqzdG+GJS9VcXsDjS72Mh6vB7rF6s0/Gl3IHY0ijgX3MwVvx/EMjZOYO9jNvGyYb2Y7Px/CSez9VnFeDkVpAK7tG9woSYVNOgLFBcyQKgiNkstlJyqJOqmYv0YSDhwONnPkNwH2qD1o+AFm6kkx9ZsXAxyplDLC+7S1S66zZwUtTl64/YaHYMxWr1FvCxDUHQWJXbVn9kx8v7XghKOfnnxwUGLwvz8hVmzHZYQwE/5px4vIX5a7sm/FVAXP5S8nHRbvfWSKR5qkLg8i50mL10ZK78B4oXjO7juK5K7QEPXd/JnchwEV2uwes9NNp8Gtg4ijr6VCVh0LCK7E+3G4XuPJyCzPdSX2Q42e5YEDkXy77BA1Yxh9kPJPiQv8F77bFQebxoHlMkcF54rsNu8uL5Bj4SnLI4vmIaJjWO45H/WJQ0UEIXmMoZ2IBNwQb15uDgpUNqG14tN58On1qloHV9xjoCXZwybV8zReeSOjTPJVq82+OAklS4kHiGV7J5SOML1hLfop6OXkNAOyG1AWU/7xGDgi9pfQABQovt/XYiiWQjrdAsYke6nRFY8adsnfYNrkqy4ODxO/DDi3t1w/HfJN5Gr9hMkYKYnoLJ4QPxShT/kMeorVi6tuMzx+JBww==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__.'/LastCheck.class.php';
 
$job = new LastCheck();
$job->run();
unset($job);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/last/icinga2.conf
0,0 → 1,63
// Put this file in /etc/icinga2/conf.d/...
 
// VNag - Nagios Framework for PHP
// Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
// Licensed under the terms of the Apache 2.0 license
//
// Revision 2018-10-01
 
object CheckCommand "vnag_last" {
command = [ "/daten/vnag/plugins/last/check_last" ]
 
arguments = {
"-u" = {
value = "$vnag_last_user$"
description = "The Linux username. If the argument is missing, all users will be checked."
}
"-R" = {
value = "$vnag_last_regex$"
description = "The regular expression (in PHP: preg_match) which is applied on IP, Hostname, Country, AS number or ISP name. If the regular expression matches, the login will be accepted, otherweise an alert will be triggered. Example: /^DE$/ismU or /Telekom/ismU"
}
"-v" = {
set_if = "$vnag_last_verbose$"
description = "Additionally list logins which are OK, not just the logins which are suspicious."
}
"-f" = {
value = "$vnag_last_wtmp_file_mask$"
description = "Filemask of the wtmp file (important if you use logrotate), e.g. '/var/log/wtmp*'"
}
"-e" = {
set_if = "$vnag_last_emptyok$"
description = "Treat an empty result (e.g. empty wtmp file after rotation) as success; otherwise treat it as status 'Unknown'"
}
"--ipInfoToken" = {
value = "$vnag_ipinfo_token$"
description = "If you have a token for ipinfo.io, please enter it here. Without token, you can query the service approx 1,000 times per day (which should be enough)"
}
}
}
 
// Example usage:
//
// apply Service "example_john_logins" {
// import "generic-service"
// check_command = "vnag_last"
// vars = {
// vnag_last_user = "john"
// vnag_last_regex = "/Telekom/ismU"
// vnag_last_wtmp_file_mask = "/var/log/wtmp*"
// vnag_last_emptyok = true
// }
// assign where host.name == NodeName
// }
// apply Service "example_mike_logins" {
// import "generic-service"
// check_command = "vnag_last"
// vars = {
// vnag_last_user = "mike"
// vnag_last_regex = "/\\.unitymediagroup\\.de/ismU"
// vnag_last_wtmp_file_mask = "/var/log/wtmp*"
// vnag_last_emptyok = false
// }
// assign where host.name == NodeName
// }
/trunk/plugins/mdstat/MdStatCheck.class.php
0,0 → 1,137
<?php /* <ViaThinkSoftSignature>mKTo94dd1u+i8HKvlQf3rPtiaEvY3sU5RuGBEWnFGFbKo1WomvGZiQ58cl1KqKOu6jf/DTuB6RmPuUku+7Y2oVS5IebUkUkt+TaXFBl7cUrOp9kkr8BjxTKDBkBvYTM6cGVUg9ceVBpDWkvmSvvkLCFabkOh8fmJsEifjyGrgIRjGCIhuY8DhwAjWz78+XosG/HnfYcf5Tpr6e/E7axGpEaVbBnb9otEG1CslG81GGDdlQp2/s35CqSMn3MBfL0qQxRwkvLHv5u345qDpgPmGL4mcK1bKQ7B4nNHFEn4qQQeuRPmZ1fLGrUHcmJGOH6Jy4hUMrnMe4yb9rpxxUPr6CHt0zI4QiW05pBTLwtQbmgRHll82LirDuSA27H4KtipGh+TuFMlZd1ixv7KcenO0YrVPU4SXV3XweaQT/luqLSVnajHVsXOIu4+FCCpV4AY07ppYtjbt9qbP6DcmbktbjiOFuHedAVC0L9448svSWHMDcOWdbAtpVhgajO9yTzMJblNvg558GrCR3YT+ol8SbU5h+iQCdPrtwETamtDGUw3p9kZIegGwbc6U+OjIbVnqKIPiNt13/4+uHcY8BZ+1BpGtPPfM1kR9c7yWkTJqkMEFFSp7ulsPfYN+pM66HFxMON8xQOOUv0tVST1rgey7KtE8/xzwLLjTIW3nZYoS9MPkTSqzijC8KYszhR0OohEYyQYle3+L2QTVd9ANakTCmKGhJ6t+dJeHzWXY/FFFeT019vVKTT03v51/olpUWV+/xs2joK9Dcb+ovTFvDQIMf3FTqlCCU1HOmj3F5wlvNJTZituEgo/9POFBmYdFSJnrX6JkPglDeJI7CmmPzxj+ZZxzaZjAOjAU4izd40N+xQx4RrI87++n44O7yBCv59UTrgIDEnhgKscQR9yMoMK5sSqKfbEaXk7L0un5evTgKeP3ZRvS2zftKWsbsEgd2zl0EjCZz599at2N4WawoWndSN0H1RyPLYncSJG6wS5QB9MgWt8SuUJMZfFJy4lETtstjdP5XQvz9VBbNAra3a+xRGzY8e4Z0JKzsV1jy2SDJ7cIQMW7Ci/NS2kghaKZl9T7CL+MITnbNeM2iPrQYYKSmnHxZi5keTqZ72Ahr6rB8Zck676pUX9AucqxT5+7Ox2QrP+IfuBnTDCCPavJ2MFAlCHp9bGdrjT6lcC1sfYdb1WlhYjqwbwXjMRsbg7NMhiaxSQ+Ozz/eJM83wgmo6Ql/4cFyhwqmKUj7d/d4q/q0TFh2Rh4uuYqpQeAZkAJHgXlJt8mZigOU9ieA0m6EhaEmr22N2Ac0Fgjr4qIbNTabu4Cd6Or4h8mZcwGBcE0/2zZZmQWNfn6hxpZ6/usd0fcQ==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-11-04
*/
 
declare(ticks=1);
 
class MdStatCheck extends VNag {
public function __construct() {
parent::__construct();
 
if ($this->is_http_mode()) {
// Don't allow the standard arguments via $_REQUEST
$this->registerExpectedStandardArguments('');
} else {
$this->registerExpectedStandardArguments('Vhtv');
}
 
$this->getHelpManager()->setPluginName('vnag_mdstat');
$this->getHelpManager()->setVersion('2.0');
$this->getHelpManager()->setShortDescription('This plugin checks the contents of /proc/mdstat and warns when a harddisk has failed.');
$this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
$this->getHelpManager()->setSyntax('$SCRIPTNAME$ (no additional arguments expected)');
$this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
}
 
private function getDisks($device) {
$disks = glob("/sys/block/$device/md/dev-*");
foreach ($disks as &$disk) {
$ary = explode('/', $disk);
$disk = substr(array_pop($ary), 4);
}
return $disks;
}
 
private function raidLevel($device) {
$level_file = "/sys/block/$device/md/level";
if (!file_exists($level_file)) {
throw new VNagException("Kernel too old to fetch RAID level of array $device");
}
$level = file_exists($level_file) ? trim(file_get_contents($level_file)) : 'RAID?';
return $level;
}
 
private function raidState($device) {
$state_file = "/sys/block/$device/md/array_state";
if (!file_exists($state_file)) {
throw new VNagException("Kernel too old to fetch state of array $device");
}
$state = trim(file_get_contents($state_file));
return $state;
}
 
private function check_disk_state($array, $disk) {
$disk_state_file = "/sys/block/$array/md/dev-$disk/state";
if (!file_exists($disk_state_file)) {
throw new VNagException("Kernel too old to fetch state of disk $array:$disk");
}
$disk_states = trim(file_get_contents($disk_state_file));
$disk_state_ary = explode(',', $disk_states);
$disk_state_ary = array_map('trim', $disk_state_ary);
 
$status = VNag::STATUS_OK;
$verbosity = VNag::VERBOSITY_ADDITIONAL_INFORMATION;
 
foreach ($disk_state_ary as $disk_state) {
// https://www.kernel.org/doc/html/v4.15/admin-guide/md.html
// CRIT faulty: device has been kicked from active use due to a detected fault, or it has unacknowledged bad blocks
// OK in_sync: device is a fully in-sync member of the array
// OK writemostly: device will only be subject to read requests if there are no other options. This applies only to raid1 arrays.
// CRIT blocked: device has failed, and the failure hasn.t been acknowledged yet by the metadata handler. Writes that would write to this device if it were not faulty are blocked.
// WARN spare: device is working, but not a full member. This includes spares that are in the process of being recovered to
// WARN write_error: device has ever seen a write error.
// WARN want_replacement: device is (mostly) working but probably should be replaced, either due to errors or due to user request.
// OK replacement: device is a replacement for another active device with same raid_disk.
 
if (($disk_state == 'faulty') || ($disk_state == 'blocked')) {
$status = max($status, VNag::STATUS_CRITICAL);
$verbosity = min($verbosity, VNag::VERBOSITY_SUMMARY);
}
if (($disk_state == 'spare') || ($disk_state == 'write_error') || ($disk_state == 'want_replacement')) {
$status = max($status, VNag::STATUS_WARNING);
$verbosity = min($verbosity, VNag::VERBOSITY_SUMMARY);
}
}
 
return array($status, $verbosity, $disk_states);
}
 
private function get_raid_arrays() {
$arrays = array();
$devices = glob('/dev/md/*');
foreach ($devices as $device) {
$ary = explode('/', $device);
$arrays[] = 'md'.array_pop($ary);
}
return $arrays;
}
 
protected function cbRun() {
$disks_total = 0;
$disks_critical = 0;
$disks_warning = 0;
 
$arrays = $this->get_raid_arrays();
foreach ($arrays as $array) {
$level = $this->raidLevel($array);
$state = $this->raidState($array);
 
$disk_texts = array();
$verbosity = VNag::VERBOSITY_ADDITIONAL_INFORMATION;
$disks = $this->getDisks($array);
foreach ($disks as $disk) {
$disks_total++;
list($status, $verbosity_, $disk_states) = $this->check_disk_state($array, $disk);
$verbosity = min($verbosity, $verbosity_);
$this->setStatus($status);
if ($status == VNag::STATUS_WARNING) $disks_warning++;
if ($status == VNag::STATUS_CRITICAL) $disks_critical++;
$status_text = VNagLang::status($status, VNag::STATUSMODEL_SERVICE);
$disk_texts[] = "$disk ($status_text: $disk_states)";
}
 
# Example output:
# Array md0 (raid1, degraded): sda1 (Warning: faulty, blocked), sdb1 (OK: in_sync)
$this->addVerboseMessage("Array $array ($level, $state): ".implode(', ', $disk_texts), $verbosity);
}
 
$this->setHeadline(sprintf('%s disks in %s arrays (%s warnings, %s critical)', $disks_total, count($arrays), $disks_warning, $disks_critical));
}
}
/trunk/plugins/mdstat/check_mdstat
0,0 → 1,20
#!/usr/bin/php
<?php /* <ViaThinkSoftSignature>1uCl6QOzHsqM8G6oAGASFqvWPi7eqBE64xZy608ielwHri6rFPPawaYvpzEjAo7fTup4TrbWcy2Y13ze6bIyW+IV3kFA4PqESgieN4VOZLJCoCmhAzSWqsVL29V3FR+RbnsBxPnm97nvwbtpSF58dFzsDs2XyeU4YAyxvApqvOX4tnc81W5jmmXEOlj1+pgOjvKCspZ8aR9eEdMblCSgpesRPu5kBhJRITdI/1l1SPDv24Q/aNzZ/ewYt5C66ZHxYR/AiWJoLXF2dg/8CAxzlCWbd16vTjY8rp96qPOrL1V0oZM+8SdN+3n4Hqr/tPwdr43WmEc2wOoEh9FzDVqok2Or/3YIMWo0Fk0bTg6GM4RoND3FJLyZ7zeO4IwQsfz0m+eZV9Kwx2QAcuLaElGoDxwCKy/PNrmog7AN2hNXq0avJ8M3/626bEjX7RgUj6gxd2Qib14gM6CWRXcOGmxTl4YNZosw6fyQZ6hRT07ndLugyZns5v9neMaVpDMvEjm9Sgi1RcD7/MISOTH6+nUt3crqNJL9X1JF8/LTI1DGnG+p92fX64n16B7Jcgt5Z4K0Od5lvPNyxNfXDuJCKm+uyw52l+TGr8m+RpMwh7JKMJhvkBRcJrekwgw5znFytl5ATGno/NKkj9Bvp2ExsZLW9jbknmolboZm6r1GkD/IJcxydBOLR0lghaJ3vRx0uE+OCnut3x5kcJnVs8/2Rok5kF9qWg3WYJvX20x4TCEvN2v/Il4iSCSQIBSpGt+0o2x8S+fuxvU+Nrn6IyGlEldFHNqOIcK5AxBv1mjxDn53xUhmzLEHNLR/9abxv+ob7gQEuJMdFl5ubQyxj/LeuAfDTEKY+ein8ZS0kjwBtJyYonrYZh2feRn42FSXZz9cmzcN/92LYPlZ86IeL+/49TMnzUcYFOp6kdtsLTDUM3cUZLcZtjnnwKQR4UNvHEfXfQTmM7MjGYDATztVHgL+STHbaGgBrt0FWBF6mu2r1v6aR3zWsJ9yXuMeOd5dTLwnlpptClBru7q6sBN55foLS78d2Kx689ycguB8S96J8JYMpGDpFeq4s5Gq2+5hiI8bAqNgtMhwGwmDJn3E8Pa17GVSVqDi7/QPRFWa4AcSD553uJxxFLZXbIrhHdrF+LCjXUn1KgOjBjuDoa8TAD57KhYOJnEPo7hi3JcaLmXb/DTlzC1AyQNkUKMGKksvsKLZ+dYSUUanWnu0l3FgHL9MkdVkJkm6BxIp+J/HOtos47mxyNLddOdFHqhNhTVI+py/oxDIsFFLP6ZH8wWo8fovUj74mDWFq7Z5FhftuPPr81cHmj+t74wffzYozrRnIaq880zRnC+f0mjvqJqX3u8jnKwp0w==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__.'/MdStatCheck.class.php';
 
$job = new MdStatCheck();
$job->run();
unset($job);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/mdstat/icinga2.conf
0,0 → 1,29
// Put this file in /etc/icinga2/conf.d/...
 
// VNag - Nagios Framework for PHP
// Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
// Licensed under the terms of the Apache 2.0 license
//
// Revision 2018-07-15
 
object CheckCommand "vnag_mdstat" {
command = [ "/daten/vnag/plugins/mdstat/check_mdstat" ]
 
arguments = {
"-v" = {
set_if = "$vnag_mdstat_verbose$"
description = "Additionally list drives which are OK, not just the drives which have failed."
}
}
}
 
// Example usage:
//
// apply Service "example_mdstat" {
// import "generic-service"
// check_command = "vnag_mdstat"
// vars = {
// vnag_mdstat_verbose = false
// }
// assign where host.name == NodeName
// }
/trunk/plugins/mediawiki_version/MediaWikiVersionCheck.class.php
0,0 → 1,81
<?php /* <ViaThinkSoftSignature>TvlSnBB9oFkMG8t23W8SFnhWVFc86YGpHfet/Nbgyd080A7CHl5DO+RWvS7H19uskpIrRBrXZYgt5c1gawuV/u0sH0F+7gJNIGcjO3kaqWzXeaceO4pvNjjPJwLShLq+FbE9kyw08XxHYYHkoJhtxnRiqaEEq4zmQ8U7S+JOnCHhP6cL3eP8/iY0jVFonPpwIcpIKHEd9p5/t5ZIFW02HCSB+wRT+jSXHe9TGieS9Yc7cODueJ80J3Jkh/EDbTOlgiOkgCROGf5zWqZUGaogvaLHk6WmO/XNyP1zUFj0lvNFfK4rhqbSy1Oa6UX+ZlVmpHAXLIR3nrpdFyYR2/zj0wXd21MpG5sN7zGgW98IpvJVSkb9eqsRr7IzmKkGvaEQ55lNYxYVgOQLOo+D9d5qb3V9stJ1R7h+VAN5uouMAd3Kj2uGp1QTUoxzy/cp1UU2ub9zQ8Q4WOvnm0TVaoyFnpptfXvRMIHbfaB4wshglKwnDvzPtQnlsJfq2R9lZ6zqvgEuIEnJtfpk6FOjCCIYR55IO1UVVryBqBWHtRBT2Y3Z0Tg5A1kuqwVcsw0d3rHRrjyhMu70DyMr4aHs1HE042coo4uYfkhmlETSNQgNntKyKcgdon/kOqxxhlc3NGopO5JVR5wBgYmX3tBYJ5OcFEzXgD4mmaF+2MG/K80sxh8t3jg+XCD7oq9dZTAAthWc7ojuWNb3a91uw6gb2lfogiCBSyCyMVRdakeA3gWZ/7zYhzWshW1sU+vegpIkTUt9Atq17k9i6WDI8wNctTvx3ItmTencuUNXmfGyrFC4iUkHlYJy8JnuC4da568M+AX9kxr/qgtsC4yhjRj+ZuEeZgVqBmYt3OIDMgdzK97+e45c0ixe4AAutbAvY00W3NiKOVe/cvYlefCxX0NjBqQ/+1gh4vhsf9Hew5TMIvlvgAVGNwGt4mQfNjcVjXk/QJb52EZ/EsKJbkBqeQqg7jrkgxH3aDhAnCKDVhjBBThQJanjAeCte/EEU3I3jnkYEktBEG6aVcYLPwC+b7joc+KMB23YhlGPfTr1dalKGp+rBLEcZQtIRPRHgsxmWpQbRqjJ6YiEhdB7RafpoN+aalxr8t1BRXiBFvOHSi/UZsRyiMjopKTMHTKuwV+TgWkgatr5oMhUYjF25bHLep2vjHBOLBcLbkvofUMYcC5SzwaT1QbzHmkPNRDMB9X5ghXgCStXGwFnbGZud+GfSnKvpBceAOxpuBgY8qVQipDeuTN0nKEkmjRyIXjsHtcBvJiYk6+7v32xC/QSXP5zdu+1bDQXqx1O1uRtC49kgX259WivMmv/TXaPc/9LMevM1eZIJ0QnMZ3lJFNCmdYr9GTklIIlDg==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
class MediaWikiVersionCheck extends VNag {
protected $argSystemDir = null;
 
public function __construct() {
parent::__construct();
 
$this->registerExpectedStandardArguments('Vht');
 
$this->getHelpManager()->setPluginName('check_mediawiki_version');
$this->getHelpManager()->setVersion('1.0');
$this->getHelpManager()->setShortDescription('This plugin checks if a local MediaWiki system has the latest version installed.');
$this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
$this->getHelpManager()->setSyntax('$SCRIPTNAME$ [-d <directory>]');
$this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
 
// Individual (non-standard) arguments:
$this->addExpectedArgument($this->argSystemDir = new VNagArgument('d', 'directory', VNagArgument::VALUE_REQUIRED, 'mediawikiPath', 'The local directory where MediaWiki installation is located.'));
}
 
protected function get_mediawiki_version($path) {
$path = realpath($path) === false ? $path : realpath($path);
 
$c = @file_get_contents("$path/includes/DefaultSettings.php");
 
if (!preg_match('@\\$wgVersion = \'([0-9\\.]+)\';@is', $c, $m)) {
throw new Exception("Cannot find version information at $path");
}
 
return $m[1];
}
 
protected function get_latest_version() {
$cont = @file_get_contents('https://www.mediawiki.org/wiki/MediaWiki');
if (!$cont) {
throw new Exception("Cannot access website with latest version");
}
 
if (!preg_match('@/Release notes/([^"]+)">@ismU', $cont, $m)) {
throw new Exception("Cannot find version information on the website");
}
 
return $m[1];
}
 
protected function cbRun($optional_args=array()) {
$system_dir = $this->argSystemDir->getValue();
if (empty($system_dir)) {
throw new Exception("Please specify the directory of the MediaWiki installation.");
}
$system_dir = realpath($system_dir) === false ? $system_dir : realpath($system_dir);
 
if (!is_dir($system_dir)) {
throw new Exception('Directory "'.$system_dir.'" not found.', false);
}
 
$version = $this->get_mediawiki_version($system_dir);
 
$latest_version = $this->get_latest_version();
 
if ($version == $latest_version) {
$this->setStatus(VNag::STATUS_OK);
$this->setHeadline("Version $version at $system_dir", true);
} else {
$this->setStatus(VNag::STATUS_WARNING);
$this->setHeadline("Version $version is outdated (Latest version is $latest_version) at $system_dir", true);
}
}
}
/trunk/plugins/mediawiki_version/check_mediawiki_version
0,0 → 1,20
#!/usr/bin/php
<?php /* <ViaThinkSoftSignature>X4GAUZ8xJBGYHJ/Sp3ZPsIAKrWkrPHzvS7SPv00eNKfF2h3vn9VWMuJqHXdAd46LEjb/1wbR4g69gkNxkAVPmn5IKbgrZWzPcwRnRs6o4icaWnY+uagKvp5Ic7PbXcuSLGUoCfa2HOxAbmuPzCjESkgfBejm1QhwxzKYzjiUBWvs5pXW5Q4+dH9m2ZfUoETmcWbw96rxjvf+asTxtbdvBzH+N9FKdtlLQ8tDoTR2zHCEnm3rvMIyNmj51kW27aS0thr4odvWGsVPP3akKUng5vb5NPvexu0cbzJltuHT4utf5d5BicNiD+4ID2Bv5fv318uilxXv6sGBrsBOfSGhigD3maozuLWQe4kC2nNLTscHhy0rWerIHOJNXasmYk/vIEHFLGetxN31NYmGJ5VFzH/zoahAW4B3Kt9E9RHReySoSKTpyr9wHDlOiLVGawhJN8sDAqtK9WD9mhinIOXzeY+tRcba+yYSewKbZMuHTXU9vtR3ilje8ER4NGER8aMyPpy3XOc40mPcggPhLVjcSu9PZlFyFLJvOGnx7I68aGAbUT46WpeD7s8DE2h8jfGlsMajgP0pMSVvdKyUs0hcSgJF4DjI8AUCjeSDKJ2SWMHMKSm6QEo26jE5ecu2AzLLY6gjYUsIqEMu55Ei4u/2SJrD1rsIFtNjBjwFmxW9JV3CU7cUGXrlvdV34kiw0PcFjM7GBPIrsDJh0bH1t0QS3S282OSgcInlfjjGEdanj0sLiWZG4SFtehJ6ojhe48NMFAPN8vjmvyPNgFFa8/H4so2CYn1P6Aq1gUgXlVVU4yXK4DBCikY/m2jgLoL5Zo2SItSIBxjyRgbE4uBlo1hKrc69v1EKnUgei5HeOTswCtpcB7eHH/+stnDGhhebAKVbh+MU7NX3zAS/tubvKdi54a7lDTHThERmtDaUdz4k0U/wbcs9jBNNBsVaGjfc5iSh6SDvlIoAcT/HH4P40p8qyNnl35cN1vpMteNgnM65/evacEd8MxFvxNnawj3nQaDAZUT07mHcsYDUk1Gt7Y2sv+02vrWF81Yfb6/2OSy5auCn89zUDVeio6knl3laj/gikhkRZ+xSAY6hWQZ8CAdqnzfUEKGCqiKIpdY5SW7Fraob173KtBOq/c30Ylatuws3MJFktkjSBfV4VtkFJabrzeuiTNd3cdq5ijAKcwc097YbLrmH0yfPuNDxTitoZlOYxiPartYFAsCHrBjSGjnu0GGMzPUCKKIWs+fYkYGowRnGdh+OBaSh8NIQCcq7geEOugUK2w0pUzRBsDYGaiD5Gct+EI9VsZRTC4V+8XoQRaPhthXVJLJw5vVodIgWc+ZJ3znG+xieX3U1Fb9wM7gydA==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__ . '/MediaWikiVersionCheck.class.php';
 
$job = new MediaWikiVersionCheck();
$job->run();
unset($job);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/mediawiki_version/icinga2.conf
0,0 → 1,48
// Put this file in /etc/icinga2/conf.d/...
 
// VNag - Nagios Framework for PHP
// Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
// Licensed under the terms of the Apache 2.0 license
//
// Revision 2018-07-15
 
object CheckCommand "vnag_mediawiki_version" {
command = [ "/daten/vnag/plugins/mediawiki_version/check_mediawiki_version" ]
 
arguments = {
"-d" = {
value = "$vnag_mediawiki_version_dir$"
description = "Location where the MediaWiki installation is located"
required = true
}
}
}
 
// Example usage:
//
// apply Service "example_website1_mediawiki_version" {
// import "generic-service"
// check_command = "vnag_mediawiki_version"
// vars = {
// vnag_mediawiki_version_dir = "/var/www/website1/mediawiki/"
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_website2_mediawiki_version" {
// import "generic-service"
// check_command = "vnag_mediawiki_version"
// vars = {
// vnag_mediawiki_version_dir = "/var/www/website2/mediawiki/"
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_website3_mediawiki_version" {
// import "generic-service"
// check_command = "vnag_mediawiki_version"
// vars = {
// vnag_mediawiki_version_dir = "/var/www/website3/mediawiki/"
// }
// assign where host.name == NodeName
// }
/trunk/plugins/net2ftp_version/Net2FtpVersionCheck.class.php
0,0 → 1,94
<?php /* <ViaThinkSoftSignature>b9H+o+uc69uskKoarZ6sudOUcbQewFqoqOw7j2C41tLdtnY5lifSSr4xHIOsORG8zuE4sWz00lp+ySbp/5Cn1wZVLpkusQSkVQZNfaYXqcyhxbpxA04qB4oUFfsecJ4lGP8cGHxT1BTxg5P81CelT56Kook+U/npTQzOXwCNL+5E/QipYUcKyh72B3+Or4lS+HPyP+WHC45XkTyvkItnCXDbsZxQR/oO5JKhv9R8t3oSHoUMX3AjCws5ZzFJ6QlHVl3zQ4u2o7MXIvYzHiojLFx/ycQ4W3AZ8xsfDRtdisIluwQ37rnQ65gxBe0YMzTjOtKWgNjr/Minaz8Tx3iSEpqCDmtoTM2lKiyf8I73wrFFiDM9BTHy9AO1Gg6lHUQGdG7URusohNh0mLanV/S69UF8EPMzbuJzfeRBd6/eYagge5yIImCLmN/YQdudfM7+ZAlQWXWjaXIRpMIJZcl8cO002xw9MlMfJRXdAJ8yUduLW1ds8b8SkxdDmWlSnNakoIRbGbuoBamN3e6od2Xdy9XIOj4GQakS5cqxxEbMOUGiTIuhKmplJD6xzHCYzIsxFe2n9gCkpGPkNuUwzb6pjS+WSIsltcsBPWu6WaWXp5D7kqspbgm7UrAprZuNojcdn8ymfBo0J+UcpYCWZhnwsjSGjIRJ8zmfedi46eYevSbVWrkZbywdNRv+UdEpTNd/20QQUGzvHbPzsIZMgwL3rDR7j5oJ2nLTygBQhylnzBhzOVdnVJyfaWwJFZgnZUBsL+U+FWF+YHeWZGLkrIPnUzIEcyb3uiYT7VWHl+B7HVDyVdMiT9CyjrYRfdP02KShkLgMl/RQcLBfnxPasSNd1PKWn7G9WoZKvy+d8cE8BrNHnnx4+NoTelV3FSG4gFlX5GlBX4/zxrK5/VPIsfxpDfrH+SqoEgefwnrM35J3hgJmDJsX/L2xwutWA4FuXHQOphEZOWKZAMM5avwZS5Zaig2C1hEbocp+NayTFgXNqjzpLbaZB6iKp4aY9Hm2ZqpY9gPTufdi6cv7vu15QYiIYcr4GmWqciDUZB9IuN8180OZGP1HtCCqzsgZZR38kO4fqx5DTzQEn6mdat9h472K+nF0rrGBRvMKq0yGIX5LhDyn+sXsFuNZOyNJWiuanDDJdTxFWyTA+0X3gzD1N5lHD1haPOp3Zv7eM/ppkGGFY69b1/mxcH8Lcre1TCxOSpG+yM+CaZy4jQSStHmXDm8z3ZJbe+DgawW9TUJg0r6Mrqer56sDgRVw2GuLkWfxCoDx1n3EoelggDhV10tTttGFEIQ2m/ruXQ4Ji/S8/gL6oaiBaIsX3PUomLFTvCSfB9TqHKX3yyCsGlXTzwSIoi+FBQ==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
class Net2FtpVersionCheck extends VNag {
protected $argSystemDir = null;
 
public function __construct() {
parent::__construct();
 
$this->registerExpectedStandardArguments('Vht');
 
$this->getHelpManager()->setPluginName('check_net2ftp_version');
$this->getHelpManager()->setVersion('1.0');
$this->getHelpManager()->setShortDescription('This plugin checks if a local net2ftp system has the latest version installed.');
$this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
$this->getHelpManager()->setSyntax('$SCRIPTNAME$ [-d <directory>]');
$this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
 
// Individual (non-standard) arguments:
$this->addExpectedArgument($this->argSystemDir = new VNagArgument('d', 'directory', VNagArgument::VALUE_REQUIRED, 'net2ftpPath', 'The local directory where your net2ftp installation is located.'));
}
 
protected function get_net2ftp_version($path) {
$path = realpath($path) === false ? $path : realpath($path);
 
if (!file_exists("$path/settings.inc.php")) {
throw new Exception("Cannot find net2ftp settings file at $path");
}
 
$cont = @file_get_contents("$path/settings.inc.php");
 
if (!preg_match('@\$net2ftp_settings\["application_version"\]\s*=\s*"([^"]+)";@ismU', $cont, $m)) {
throw new Exception("Cannot determine version for system $path");
}
 
return $m[1];
}
 
protected function cbRun($optional_args=array()) {
$system_dir = $this->argSystemDir->getValue();
if (empty($system_dir)) {
throw new Exception("Please specify the directory of the net2ftp installation.");
}
$system_dir = realpath($system_dir) === false ? $system_dir : realpath($system_dir);
 
if (!is_dir($system_dir)) {
throw new Exception('Directory "'.$system_dir.'" not found.', false);
}
 
$version = $this->get_net2ftp_version($system_dir);
 
$cont = @file_get_contents('https://www.net2ftp.com/version.js');
if (!$cont) {
throw new Exception('Cannot parse version from net2ftp website. The plugin probably needs to be updated.', false);
}
 
if (!preg_match("@var latest_stable_version\s*=\s*'(.+)';@ismU", $cont, $m)) {
throw new Exception('Cannot parse version from net2ftp website. The plugin probably needs to be updated.', false);
} else {
$latest_stable = $m[1];
}
 
if (!preg_match("@var latest_beta_version\s*=\s*'(.+)';@ismU", $cont, $m)) {
throw new Exception('Cannot parse version from net2ftp website. The plugin probably needs to be updated.', false);
} else {
$latest_beta = $m[1];
}
 
if ($version == $latest_stable) {
$this->setStatus(VNag::STATUS_OK);
$this->setHeadline("Version $version (Latest Stable version) at $system_dir", true);
} else if ($version == $latest_beta) {
$this->setStatus(VNag::STATUS_OK);
$this->setHeadline("Version $version (Latest Beta version) at $system_dir", true);
} else {
$this->setStatus(VNag::STATUS_WARNING);
if ($latest_stable != $latest_beta) {
$this->setHeadline("Version $version is outdated (Latest versions are: $latest_stable Stable or $latest_beta Beta) at $system_dir", true);
} else {
$this->setHeadline("Version $version is outdated (Latest version is $latest_stable) at $system_dir", true);
}
}
}
}
/trunk/plugins/net2ftp_version/check_net2ftp_version
0,0 → 1,20
#!/usr/bin/php
<?php /* <ViaThinkSoftSignature>l0JA4IkbQaFh7/lVbSy6ZTKB4YMwSN+xXuqpigYbfIoaLjM/WBDSCJT2moaq801hwR/dik8kia16RHMzr1msT78opQMN1YveP6qzWZOkJkC98JlvaHay0qpXoCOLQMzXB5hVvJUVEFBqV+M6nNa09RMoTpVQXDmoF9Y5ExMDdZvyoOuyVBiAN4JALb03Rs3Nkgx5Y0N3Gtj5GQOm3+yiblt8WW5rCqxya2abVzeSo3Z0HRtNfT+yrVw2pCoVCaBklNbiKbE2q56o4+P6g1Qc2I15qUIQ9via1ANoPlbOEpIRBBpvbrtYvXBMIjqjQDTvysO7aL3JTBHyaI6L8B727CQ+7gIFj0AoC0k14A+M9gBPnvj8imi3ovu0EgPSh1i/miWwuDFCXVy8rsifyzwlcPIN88Ygcuye3Gq5mLOGHbdxV0Uyz3Yw+/5GldH1XUiUudlCgD8bKkBSAptVmJk59wi+WgBPdAXW3Bw+9fZxqDO4p2BkaculYmDs3VfLyry1AhLc25kJ09+AK6oRqLMGck8GHbdTM5XVW4+NtT/+AY69BNiHSfDLOBBN8jLM3OblGZTkBZEz8v1gdvURnCDJqCWETT0dtZ4Nh/BEi0oVvTGc2yZOsIs0E+IlCFPfZJhkgqf39EL8HjHt8hgIjdLye8XJYCtEHzq/8p0TFZP9DJF8jKfpaeZvZPXtT4tjY0ul/jNLCRItx4G7EtqVUA2CbvKwapYcjTbdZb+KKDQmOZDDvFM1WEtmWvT5NDYDItYbZsTblOcKDDBLHDrGJbVK3ZLTu6IRJbA5ZqSECAKC1W5YUD02hlNIT7JgM0wgRnibkwMeO3o3OwuCDpJk4P1lPalKdK0zNx3EE+g+Mjp/s7DKf80LG/WMYjwxzGzXIr1+hBJeD1y0nt4TT97/6rY+N4IPaycV2sM1cUmenOX23Bo7y+KuClhq3PLD5eAbY51XJMan7AIkNJFQjuYURYfZkSojkjnBLEPZNSuiTDr6rYf8r5Bl+IeJ6x8V7o3mwP6heiGxARhh2lYD9LmKGV4EjO7AogBJZ6VSZhXhvKpm/SXsbncQoVpb0ty2glW18zbDZRMewTeQQ32nFouAQ/h4WGzvGEwEuHIixBHCLcFL6xciWHWOwZEXe3Rbh5oZMMfpNTTx+m1rx3Fivxhy/pS/tUTk2xnTlTRJ0EJOfeWkvgOy9X4FQYg1WTRMdlE3ek56u6gyb1y9aEF7UHCRR8eiRMSsJf8WoTS2cOBu4omx8BvZVtHGlezcm7Im2KmiX4mmHctKs/sDZf3Jxc7TxGp6JXao3oyD4DrcFGAV9d8papwbBbgqRbcCarxhdpRT5U4/tlEmcGccfhRN3kCG7svwbg==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__ . '/Net2FtpVersionCheck.class.php';
 
$job = new Net2FtpVersionCheck();
$job->run();
unset($job);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/net2ftp_version/icinga2.conf
0,0 → 1,48
// Put this file in /etc/icinga2/conf.d/...
 
// VNag - Nagios Framework for PHP
// Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
// Licensed under the terms of the Apache 2.0 license
//
// Revision 2018-07-15
 
object CheckCommand "vnag_net2ftp_version" {
command = [ "/daten/vnag/plugins/net2ftp_version/check_net2ftp_version" ]
 
arguments = {
"-d" = {
value = "$vnag_net2ftp_version_dir$"
description = "Location where the net2ftp installation is located"
required = true
}
}
}
 
// Example usage:
//
// apply Service "example_website1_net2ftp_version" {
// import "generic-service"
// check_command = "vnag_net2ftp_version"
// vars = {
// vnag_net2ftp_version_dir = "/var/www/website1/net2ftp/"
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_website2_net2ftp_version" {
// import "generic-service"
// check_command = "vnag_net2ftp_version"
// vars = {
// vnag_net2ftp_version_dir = "/var/www/website2/net2ftp/"
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_website3_net2ftp_version" {
// import "generic-service"
// check_command = "vnag_net2ftp_version"
// vars = {
// vnag_net2ftp_version_dir = "/var/www/website3/net2ftp/"
// }
// assign where host.name == NodeName
// }
/trunk/plugins/nocc_version/NoccVersionCheck.class.php
0,0 → 1,83
<?php /* <ViaThinkSoftSignature>Pk9vVzhiMUsINHj3unermWodlsIIRX8gfqCE9mxoch3WXBd3FqQdASPFk8CNjqMB1bPBUTqhkSkn1gKP8qG7e1kcr8pciOd4RYZmd5HuuqNFdJFK4l8cDYSl71LgqQBKQMMLt9bygoUPVyAgN6b8B87qM6XmTsJHDK74u1OtQOaffQNIBMXvbWH8tDFrcDpKvTvQlgkNYqil/gvZ/KMSjghhh0+OTFmBFeaChK34O0vMv7PbWw2Kt/rT1jxs6sfWzGal1cLAP/wAb1/fwKP8+OsmOuRwcNjEk09/k6mc93SxGAxYvRatgNoE3QhMyJMra9iF22/ZZ2/xkubn4T83rDI+AJXzvsvqpTFezxmTeHG8Y02ufSPOl4lFT9Ds6FtRymHaLtSMrXet3r/RRO0vM8V86kpQ8iEQSPEpXNletRZ9XoE6m2fsZ+laMin+WiHibBrSgr173K/fGuk0Vw1k0oZ10DrottkQ84WBizZXNgMqmQCuXoLKbVJj+75LCGp3z6YwU2XiEXRZbcjyp2FU8LG6NLBZJq3BjnoiFppoFRG2QCqCBAbUCCKNXhCqPyxUmXTRmcusxWEwpTZPMgucGixaRgo56ta7Mp8R6SG3c1k6kvOyueIfWoiyw2DGgMTnX/WvVgbH2TEeYn1RNv5YbEdMAYrcKfFDU9gSzKwr5+KJMSuXR6MhCPRPd0x+U8wg8Spf6Ys426ZMSd1a5MuFCoVt9CgvJcdzMLnQ0bLDBtACMfldEjqM8Qg/BdfS4Fsq9glaaaN5B9/RU50qh2fY12V5kxZK+q/3Nr+Lb9Ks+x7RwivwgBNfO+D1CyDY9JsyvOlc5NMOax2tyAkd4VL5eFPqGh4YwYuY1vxd+oBN1ED72Ozva85BzSi+gJcPF8APZNgGaGTRa/Qxkf0nIEQw4XPOrxysQtVjxzfAqsyzLBqad1ZBm/ed0tzbqPVju17YCa6cKWHGiVZlPHgkcKP8CDSJN1CEG1gp7D5luov777Y3PS1jLOiCD2ZV+ZSy1fWBA8aH8M2taKyRJl2mFYqIAk657nKQa/QaIMmPDaTzGMKJGlXSyLySmkTxpkKNcl4OMDIc8NkYxhk/EJW95rXP+J8X/PNBD05wplBx0d3W0ujUSyT2zeFbTGb4M7ph0SgMEFgwP0ivfSjTh2+ChFvdU0BFz9WbBLr0lU20FYnunsQEdlmU1aMgC23+rG3KYnXwsK7xl+ZK7wcavgNYIjrpdSy5V0errT23OWv/XSjyBEIp8KN2yYpz59/p8Z90E7P67DqIO4XWKfkotiLkRxhblpbJpXynVP/rjreWXN0pNtpA6EeO6pPInpekv3/UAKyrRpI151znpA9qYqSXxV15sA==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
class NoccVersionCheck extends VNag {
protected $argSystemDir = null;
 
public function __construct() {
parent::__construct();
 
$this->registerExpectedStandardArguments('Vht');
 
$this->getHelpManager()->setPluginName('check_nocc_version');
$this->getHelpManager()->setVersion('1.0');
$this->getHelpManager()->setShortDescription('This plugin checks if a local NOCC Webmail system has the latest version installed.');
$this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
$this->getHelpManager()->setSyntax('$SCRIPTNAME$ [-d <directory>]');
$this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
 
// Individual (non-standard) arguments:
$this->addExpectedArgument($this->argSystemDir = new VNagArgument('d', 'directory', VNagArgument::VALUE_REQUIRED, 'noccPath', 'The local directory where your NOCC installation is located.'));
}
 
protected function get_nocc_version($path) {
$path = realpath($path) === false ? $path : realpath($path);
 
$cont = @file_get_contents("$path/common.php");
 
if (!preg_match('@\$conf\->nocc_version = \'(.+)\';@ismU', $cont, $m)) {
throw new Exception("Cannot find version information at $path");
}
 
return $m[1];
}
 
protected function get_latest_version() {
$cont = @file_get_contents('http://nocc.sourceforge.net/download/?lang=en');
if (!$cont) {
throw new Exception("Cannot access website with latest version");
}
 
if (!preg_match('@Download the current NOCC version <strong>(.+)</strong>@ismU', $cont, $m)) {
if (!preg_match('@/nocc\-(.+)\.tar\.gz"@ismU', $cont, $m)) {
throw new Exception("Cannot find version information on the website");
}
}
 
return trim($m[1]);
}
 
protected function cbRun($optional_args=array()) {
$system_dir = $this->argSystemDir->getValue();
if (empty($system_dir)) {
throw new Exception("Please specify the directory of the NOCC installation.");
}
$system_dir = realpath($system_dir) === false ? $system_dir : realpath($system_dir);
 
if (!is_dir($system_dir)) {
throw new Exception('Directory "'.$system_dir.'" not found.', false);
}
 
$version = $this->get_nocc_version($system_dir);
 
$latest_version = $this->get_latest_version();
 
if ($version == $latest_version) {
$this->setStatus(VNag::STATUS_OK);
$this->setHeadline("Version $version at $system_dir", true);
} else {
$this->setStatus(VNag::STATUS_WARNING);
$this->setHeadline("Version $version is outdated (Latest version is $latest_version) at $system_dir", true);
}
}
}
/trunk/plugins/nocc_version/check_nocc_version
0,0 → 1,20
#!/usr/bin/php
<?php /* <ViaThinkSoftSignature>K2/AEb5ko2ocYdyzMoVvaPV25g9LT8UY7lftmZzqH6DzSV918kgfNORcrZAYlmlFPd0hvMSXB5KcJvOLWVquVDtyZxtKwzZf+RyvtYMuwqqMbjTsoW2sECXzNkW9K+KPLnOITL/zNKSl2LJeaupA34o+xJGO2jwjBfGRMJz9qCq2+XBMW9ApzpCvRUMLIy6+WpaeQSJsHVMbcWduakEcGJQNAwLcvKDlcthcp5xslfMD/z3eB86rY5IFDDqvImvzlXOO9HD292o673ZbqSIIMZxINkGGRT7cO4sXWnBV1NSOb7Zx2EUVUn3IJR5RAB1r+7leZ2oNunAIh6Fivk8K2a35fNwkVPE4AVkVM+1JAiGnlWiWZ8T4mKw6l5k7GxsjO5oFOWpo0FS0Um9RzemIsQAGD8Ve2dNxLa/t/9rO0ADczUEFAZnffDG1ZH+VH4f9ls0yjp0YPUHfFYSGcC/WW4SyawqluoYbmQNEowzCIc25IKZTFYbqIWWj68RWZ9egfGP+EJ96XqhSrGUhK0fjNgujxO2uipnObGbpBclS4R8YFI/k+QkqcR8HeNG90dmNNrehFBTHz0W+CbY+RpUQf+fMp4PyiPPIPEE9rBnvzTYFSEyrcsq3ue9t2Lu2WiIe7Vuo3SHUyuiNiiRmNBJb4csJ2aHspL/5I0AXUl1aCnpFKIV1iXQUCcTfq6AGZXjG6RK/FEMSA0PdCMGaxHPpsZAZODURKGfMwCWbXnuZhhoKHshMx8PkZ0KkRKTGIy11U8kQze72qrWwhJN8hrx79ckBQ/UhL9OBjRI83jx1ESIlnIs6AwIER6oiSgkh7n0SiObUyK8ubZvSCv/cMQnWoAieQViRWARbcKPrPXuu1KHan8QDgoHubDehBf4KtQIAHU+dMVlglXZdAGamYZx+25RJ6Qoenh5G+X6xXN5l6neAPnETVfHI1n3/ZSuUfemu+KkTyS/9+4AuhrKIigcef0tIbn6DfqD//+encjTxi00eMGMzHHfcDfEKwwQF5ot0WXiRi5EkY6E5IARP7XmO6jxEwkBnM/trg97+oKxRO7dJBNJKZt/9sQt7AiWFWrUOsijXBH5Twvk0bJlA3yeaY13+08RtnvR15uNnAMj83QrnvmpXiAirkQ3Po642/PW2ofO8fyi8I+GhJb/ZAx6TcctW6rXgR47nfu2vLLOiRiioH7WGO3kyQYgeqCWf/G3KuivXQ1tjuuG4zTZ9UbbcqFJFD72VYjK37DKfURQdDM92wZPn85YErD4uXkZrPTNU6Ah5TmicM6LK8NcWGh2WdKSG5Uze3GHwOKv9vfhCN45TgS0tCgxBn93JES63XR6o1JhNewN3Q3WTchdsQNcIHQ==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__ . '/NoccVersionCheck.class.php';
 
$job = new NoccVersionCheck();
$job->run();
unset($job);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/nocc_version/icinga2.conf
0,0 → 1,48
// Put this file in /etc/icinga2/conf.d/...
 
// VNag - Nagios Framework for PHP
// Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
// Licensed under the terms of the Apache 2.0 license
//
// Revision 2018-07-15
 
object CheckCommand "vnag_nocc_version" {
command = [ "/daten/vnag/plugins/nocc_version/check_nocc_version" ]
 
arguments = {
"-d" = {
value = "$vnag_nocc_version_dir$"
description = "Location where the NOCC installation is located"
required = true
}
}
}
 
// Example usage:
//
// apply Service "example_website1_nocc_version" {
// import "generic-service"
// check_command = "vnag_nocc_version"
// vars = {
// vnag_nocc_version_dir = "/var/www/website1/nocc/"
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_website2_nocc_version" {
// import "generic-service"
// check_command = "vnag_nocc_version"
// vars = {
// vnag_nocc_version_dir = "/var/www/website2/nocc/"
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_website3_nocc_version" {
// import "generic-service"
// check_command = "vnag_nocc_version"
// vars = {
// vnag_nocc_version_dir = "/var/www/website3/nocc/"
// }
// assign where host.name == NodeName
// }
/trunk/plugins/overview
0,0 → 1,39
 
VNAG PLUGIN OVERVIEW
====================
 
+---------------------------+----------------------------+----------------+-------------------+-----------------------------------------------------------------------+
| 2011 StatMon (deprecated) | 2018 VNag Command | WebOptimized? | Generic/Internal? | Notes |
+---------------------------+----------------------------+----------------+-------------------+-----------------------------------------------------------------------+
| 4images_version | vnag_4images_version | No | Generic | |
| aptitude_monitor | (Obsolete) | - | - | Functionality part of Icinga's command "apt". |
| certificate_monitor | vnag_x509_expire | No | Generic | See also Icinga's "ssl" command, which checks certs of live websites. |
| hdd_usage (hdd_size) | (Obsolete) | - | - | Functionality part of Icinga's command "disk". |
| ipfm_mon | vnag_ipfm | Yes | Generic | |
| joomla_version | vnag_joomla_version | No | Generic | |
| lastmon | vnag_last | No | Generic | |
| mdstat_test | vnag_mdstat | No | Generic | |
| mediawiki_version | vnag_mediawiki_version | No | Generic | |
| mem | vnag_virtual_mem | No | Generic | Checks real+swap memory. Icinga's "swap" command only checks swap. |
| net2ftp_version | vnag_net2ftp_version | No | Generic | |
| nocc_version | vnag_nocc_version | No | Generic | |
| phpbb3_version | vnag_phpbb_version | No | Generic | |
| phpmyadmin_version | vnag_phpmyadmin_version | No | Generic | |
| positive_responder | (Discontinued) | - | - | Was only intended as test monitor. |
| roundcube_version | vnag_roundcube_version | No | Generic | |
| smart_test | vnag_smart | No | Generic | |
| static_ping | (Obsolete) | - | - | Functionality part of Icinga's command "ping-common". |
| timestamp | vnag_file_timestamp | No | Generic | |
| universal_ping | (Obsolete) | - | - | Functionality part of Icinga's command "ping-common". |
| verteiler | (Obsolete) | - | - | Functionality part of Icinga. |
| website_monitor | (Discontinued) | - | - | |
| wordpress_version | vnag_wordpress_version | No | Generic | |
+---------------------------+----------------------------+----------------+-------------------+-----------------------------------------------------------------------+
| - | vnag_webreader | No | Generic | |
| - | vnag_disk_running | No | Generic | For monitoring disks which do not have SMART functionality. |
+---------------------------+----------------------------+----------------+-------------------+-----------------------------------------------------------------------+
| - | vnag_faindex_ts | No | VTS Internal | |
| - | vnag_bulbcam_* | No | VTS Internal | |
| - | vnag_oidinfo_linkcheck | No | VTS Internal | |
| - | vnag_vwi_timestamp | Yes | VTS Internal | |
+---------------------------+----------------------------+----------------+-------------------+-----------------------------------------------------------------------+
/trunk/plugins/phpbb_version/PhpBbVersionCheck.class.php
0,0 → 1,177
<?php /* <ViaThinkSoftSignature>XTWdCCK0FEM0wejpeajPPdpwhBNotRfIAK4cUBRtt32pcQoxsNdP1sU8Zw38IEq2BP1pK8ELVVyb20dUZGQouY42DJQaTE0RRDGSfKZVxsYWAdLyiRc1gWPVsj3fHFJHJOjey16hbqsdiKLpwT8fHgqaCz0y87oeksLQOmGw1VXfbQECYz3XU1JGie+Mxbx/dZNgMb3l3juVwrs9veDBU2Q0HyeVAsV1xebfm+AfKngIV0dBEFW+kkBAcFuwzfaLIlhTC5Vt1mvs7ZVbrgFxybkTuPV0J7aHwqt9qrRUiJLCOT6Vd2JuMQisCjVecjKD6XSNq2+ZQ/YOuzuQ8HtPm3zKZeyk+PjQ+LqcoRY0i8MEXyxkHwZbBIgwko00Nw9hzSbtE0iQfDi/KtAYBr8bb3U8ufMgbRWWf3ayrDOAJ2wNVgt6CqZACtPncvdpEc0fTAMm5n7oinbC81zCpOCza9+Wka1Rl3w6forL9vezAG10K+9tn7PyUFKTxJKEUY2agFtumywKDh2tLoODZyZ8mNF3/pUeCgZFzoYgRvdRHBqc4E3Bnqb3ffB1JSaHl0FizufFv1UdHrG0EYXL7VARPHjDAXNi9EiPsudZP3XREcQpDSk01zqajMrA4s7PphLKigGcvW9nw5BTlo8i10RWzQcSsIqQNP7wibr5TZUrkSVjRZZNOOXepdGiAHapKn9h2tTcYbQb8yG5j4bGTzFQsD/9wJql+acM/sdwDR3Gn/j0765eioW3DUCp0QeTmHewerq85aL+T+GJA3cjFkk1yemgOVI9QlDFBrCe1iYnep+XxuN8vEDM/AXy1e122FCDAHACWFTE6qrbDSF5Gr92vMoQKyKtTTDJRDjrAIkPtQzSSHeyHUqKAFN2xapEiyq6rbuSQvbBnQPp+zDPkJUTV55U84JpRWmVEDe2TdUJcrJKRRGGY0kXZk75M+9L3UUDJljSzTemvMSD/kLFz0tGFHLzLguUZFlKMMQwsV/+WqQ13jl9FO8r7zmEG+9f3S2kqhQEyF+ZjmqBeSh5vb6zOzQ5ZSyPMdVcdYtOnPhKAARA3/oj9T9IB0Ybji4bYs7u2cD00yxHJ/f9yR5CRY6T6CJHuY6qduzacD6t8wrigfLQtv2/K27hpdoTOQi6oqPCy1zbF9UY6N4JpBVHnsMDv7akwPTMNTB0tuYTIHH8rcQudrJfqXUXquTgL35k8KaB+IGtGlrGq0w9OtCA199or1heFAvPzi6lGkjF5rftF/V4HpO4JZQ2lKY41Z2ZXGK75oryv2DL79h4cvdFdhR7O88AHlwlcodGTMfaKa2o51scaVjjDirWe4lZb0uXXLHDr19dDeajObnBFnukl1FGaQ==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
// TODO: Should we also warn if a newer major version is released?
 
declare(ticks=1);
 
class PhpBbVersionCheck extends VNag {
protected $argSystemDir = null;
 
public function __construct() {
parent::__construct();
 
$this->registerExpectedStandardArguments('Vvht');
 
$this->getHelpManager()->setPluginName('check_phpbb_version');
$this->getHelpManager()->setVersion('1.0');
$this->getHelpManager()->setShortDescription('This plugin checks if a local phpBB system has the latest version installed.');
$this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
$this->getHelpManager()->setSyntax('$SCRIPTNAME$ [-d <directory>]');
$this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
 
// Individual (non-standard) arguments:
$this->addExpectedArgument($this->argSystemDir = new VNagArgument('d', 'directory', VNagArgument::VALUE_REQUIRED, 'phpBBPath', 'The local directory where your phpBB installation is located.'));
}
 
protected function get_phpbb_version($path) {
$path = realpath($path) === false ? $path : realpath($path);
 
// Version 3 support
$cont = @file_get_contents("$path/includes/constants.php");
preg_match("@define\('PHPBB_VERSION', '(.*)'\);@ismU", $cont, $m);
 
if (isset($m[1])) {
return $m[1];
} else {
// Version 2 support
$cont = @file_get_contents("$path/docs/INSTALL.html");
preg_match("@phpBB-(.*)_to_(.*)\.(zip|patch|tar)@ismU", $cont, $m);
 
if (isset($m[2])) {
return $m[2];
} else {
return false;
}
}
}
 
protected function isVersionCurrentStable($json, $version) {
foreach ($json['stable'] as $major => $data) {
if ($data['current'] == $version) return true;
}
return false;
}
 
protected function isVersionCurrentUnstable($json, $version) {
foreach ($json['unstable'] as $major => $data) {
if ($data['current'] == $version) return true;
}
return false;
}
 
protected function cbRun($optional_args=array()) {
$system_dir = $this->argSystemDir->getValue();
if (empty($system_dir)) {
throw new Exception("Please specify the directory of the phpBB installation.");
}
$system_dir = realpath($system_dir) === false ? $system_dir : realpath($system_dir);
 
if (!is_dir($system_dir)) {
throw new Exception('Directory "'.$system_dir.'" not found.', false);
}
 
// 1. Checking the main system
 
// See also the original version checking code at "phpbb/version_helper.php"
// More information about the JSON structure: https://area51.phpbb.com/docs/dev/extensions/tutorial_advanced.html#extension-version-checking
// (Note: We should check regularly if the fields 'eol' and 'security' will be officially implemented/described)
$versionCheckUrl = "https://version.phpbb.com/phpbb/versions.json";
$cont = @file_get_contents($versionCheckUrl);
if ($cont === false) {
throw new Exception('Could not determinate latest phpBB version');
}
$json = @json_decode($cont,true);
if ($json === false) {
throw new Exception('Could not determinate latest phpBB version');
}
 
$version = $this->get_phpbb_version($system_dir);
 
if ($version === false) {
throw new Exception('Could not determinate current phpBB version in "'.$system_dir.'".', false);
return false;
}
 
if ($this->isVersionCurrentStable($json, $version)) {
$this->setStatus(VNag::STATUS_OK);
$this->setHeadline("Version $version (Latest Stable version) at $system_dir", true);
} else if ($this->isVersionCurrentUnstable($json, $version)) {
$this->setStatus(VNag::STATUS_OK);
$this->setHeadline("Version $version (Latest Unstable version) at $system_dir", true);
} else {
$this->setStatus(VNag::STATUS_WARNING);
$this->setHeadline("Version $version (Old version!) at $system_dir", true);
}
 
// 2. Checking extensions
 
$total_extensions = 0;
$unknown_extensions = 0;
$old_extensions = 0;
$current_extensions = 0;
$check_errors = 0;
 
$ext_json_files = glob($system_dir.'/ext/*/*/composer.json');
foreach ($ext_json_files as $ext_json_file) {
$ext_json_client = json_decode(file_get_contents($ext_json_file),true);
$extname = $ext_json_client['name'];
$version = $ext_json_client['version'];
$total_extensions++;
if (isset($ext_json_client['extra']) && isset($ext_json_client['extra']['version-check'])) {
if (!isset($ext_json_client['extra']['version-check']['ssl'])) $ext_json_client['extra']['version-check']['ssl'] = false;
$versionCheckUrl = $ext_json_client['extra']['version-check']['ssl'] ? 'https://' : 'http://';
$versionCheckUrl .= $ext_json_client['extra']['version-check']['host'];
$versionCheckUrl .= $ext_json_client['extra']['version-check']['directory'].'/';
$versionCheckUrl .= $ext_json_client['extra']['version-check']['filename'];
$cont = @file_get_contents($versionCheckUrl);
if ($cont === false) {
$this->setStatus(VNag::STATUS_WARNING);
$this->addVerboseMessage("Extension $extname : Cannot reach update-server (Version $version)!", VNag::VERBOSITY_SUMMARY);
$check_errors++;
continue;
}
$json = @json_decode($cont,true);
if ($json === false) {
$this->setStatus(VNag::STATUS_WARNING);
$this->addVerboseMessage("Extension $extname : Cannot reach update-server (Version $version)!", VNag::VERBOSITY_SUMMARY);
$check_errors++;
continue;
}
 
if ($this->isVersionCurrentStable($json, $version)) {
$this->setStatus(VNag::STATUS_OK);
$this->addVerboseMessage("Extension $extname : Version $version is latest stable.", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
$current_extensions++;
} else if ($this->isVersionCurrentUnstable($json, $version)) {
$this->setStatus(VNag::STATUS_OK);
$this->addVerboseMessage("Extension $extname : Version $version is latest unstable.", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
$current_extensions++;
} else {
$this->setStatus(VNag::STATUS_WARNING);
$this->addVerboseMessage("Extension $extname : Version $version is outdated!", VNag::VERBOSITY_SUMMARY);
$old_extensions++;
}
} else {
$this->addVerboseMessage("Extension $extname (version $version) does not have any update server information.", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
$unknown_extensions++;
}
}
 
if ($old_extensions > 0) {
$this->setHeadline("$old_extensions extensions require an update", true);
}
if ($check_errors > 0) {
$this->setHeadline("$old_extensions extensions can't be checked (update server error)", true);
}
$this->addVerboseMessage("$total_extensions extensions total, $current_extensions up-to-date, $old_extensions outdated, $unknown_extensions without update information, $check_errors update server errors", VNag::VERBOSITY_SUMMARY);
}
}
/trunk/plugins/phpbb_version/check_phpbb_version
0,0 → 1,20
#!/usr/bin/php
<?php /* <ViaThinkSoftSignature>tGwFGPF89jRw0DEFaL9yELSpMtif5ISm+iiAqLtmpqsFeQJd0T1xTFBXLdTW9qfrTo0SBCi2zcoLpa74erGAsxMaD95nimbKnQT0OqB6RUGfM523Os2ygR4tgXVXS9PuUoSfjd1vFIHW+9B225/2huT+aOYmRs4x6LQyGoVAx/zS8ToPrzz4/LwzU6sftqIaWSqpXtzLn0FIVIP0FwoNaI2aAZqFAIu+aPmfc21f+HPbeVB95jTV6Kyjmj6c6zBF2fUyRkEH7tz4iH4cK6ZNe7FUN8lEnf7P46b4Mb4KgepndSYa8tKskeQlIjoOqFC2unvD1buqOl+8jlLyECEHIsg+QL+Yt6y6557LEw1kuO3EwCZozcWTuc6y5fhKNl6fC83tFx4wGHvK9te/N0rKusvrN5oT8O1Oorv/Rgc7YUijQAiw+GHPA88Qhb4LbwDlFyCdEgLvFVbYktyVFmoCw9fXa2I9usIf9RlkJas0bVQkZnxABLK/jtKhgt7fHd6MswR+aeBXa3Wb7Isa7YcWcQFMMa1EQxG8Kapdzx0GvPJ3QE4/6aEasVa64vfdKi/30ru+syi9Of+AadjhQtak155gIEMxAIIOiPhseawMYYhItu0JdSzs9ekPBDCbzTs4AR5luSTPqlEEkLkvcor+xr1NAj4i5csP2zkSSYZza55vMPX/LRDFScTASkHA/QEykjuMqMoicyZuQpY0eBciTfwOGm01QyJ/7wlZswQKHNVPpELm0T6QgPeToRomdy+aTOFLRb5gb6mv3TLOjy04HbqVyaMqBpECFqhGWC7DmMECJbDDDisvwm+7iZRv1fEVPVwQZbXKFqQMgD1s80i7+OgJiEPW1UwPpBGM8rhoMP9urdgMrmEoqUGgBxh26K0gHvEehXVrmeR/bFWxZ/hTq0BJIipulTpxS3d8mB4AvD8kDL/cG0Xmfyrf5iW/TfYeIQHN5yBiu5JW0r98EZUGRqNr0cfROfY00Woc8GdfhQeeAyFnDSgbiYJWQ8km77XWX0gIE+LNkgKiwDghjYWZ7uJGEFIGYjui6Doys2KJoMnR6Jbj4yCc44HPp+1Ig3wXN9jkgF3/Mio5ZP3K6vEivkS+m3UAnNRnaIOScM4gy6vufNzRjCiYGVMIT44tB6Fcb4qM6U/3DvdeFwNGiT8E3zUudILOrRl/v+2JicM21JO0fq8g9Z57oBTVEByEx1ojbqncPgM7g5v8/TxnKdI6g1nLypxT/RUUoaSRhx4AqaPbXCWz4R8JxhfuGj74cKNAcWsOt1+n2tnVx3MpOTw4Jqt3yRltdiZjXbO2ZOvnz2ZwqefNIHb3eJ1EuXf898uFW2rTmBi9XbMqZdH68vjl+Q==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__ . '/PhpBbVersionCheck.class.php';
 
$job = new PhpBbVersionCheck();
$job->run();
unset($job);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/phpbb_version/icinga2.conf
0,0 → 1,48
// Put this file in /etc/icinga2/conf.d/...
 
// VNag - Nagios Framework for PHP
// Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
// Licensed under the terms of the Apache 2.0 license
//
// Revision 2018-07-15
 
object CheckCommand "vnag_phpbb_version" {
command = [ "/daten/vnag/plugins/phpbb_version/check_phpbb_version" ]
 
arguments = {
"-d" = {
value = "$vnag_phpbb_version_dir$"
description = "Location where the phpBB installation is located"
required = true
}
}
}
 
// Example usage:
//
// apply Service "example_website1_phpbb_version" {
// import "generic-service"
// check_command = "vnag_phpbb_version"
// vars = {
// vnag_phpbb_version_dir = "/var/www/website1/phpbb/"
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_website2_phpbb_version" {
// import "generic-service"
// check_command = "vnag_phpbb_version"
// vars = {
// vnag_phpbb_version_dir = "/var/www/website2/phpbb/"
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_website3_phpbb_version" {
// import "generic-service"
// check_command = "vnag_phpbb_version"
// vars = {
// vnag_phpbb_version_dir = "/var/www/website3/phpbb/"
// }
// assign where host.name == NodeName
// }
/trunk/plugins/phpmyadmin_version/PhpMyAdminVersionCheck.class.php
0,0 → 1,80
<?php /* <ViaThinkSoftSignature>q6gx+eKOBlrjudngDLewBu36ohNJSKufLoPCxcLlswvaRLCe6fNoEPFIkS4FW748JC+3c7H3HZx4oyqEztzYqaG53xpaM4jFKsRs4hYPsxLmOtXyiXUhk5bTeZzyGYQpTHIquBkUBcworlVKxaTTdipcytlq0e9bTWMNd1vivtttYdpJd+UkiaQL/Mb/AwvU62Qy27URiKSiLx356H9XQbZl7NvSxnrvDwcV/1+tAp/XpFh3F+BK88+y6hs7oNsN9D9Hc2dw3sSPH1b75HQTyDD8yyBxqGqxAEDYUNBEQPHnxYk2uLagolfiLXiyrUkJr8NewattBAECBmfFjXjOvhVz4ggPYKVjOL5i1cKviwsiHo5BFH7H5QECqUbGyHNm+Ce6IJ5o5wveQG+JCzNjH1BifZZ/dNM26PbyVyOLiFok8dc/fkdLmbj1x5hYY4nvhL92QUT83XBDzXV/2QIiiQTnwi89V3iOv4bfLEc9OcEDM0m+dKKrista+btJLw8u7NV4PXYE1U/UBpH+NjJ6uJ9nitVfOYN8LgwerGhFN/WYxjiBgRdhbux2/YQvH2V0yX0+sNn5tRLi45LRLM5VoCg56r6vhNaYRoYTeluSJ57FwMVong1JLv/kW07/wHQ0PBRs3tDEPfJnatiJxYhhJKd04QdEfYuQj5o+51u3OIDMLNh/3IQtxM1La6I7dBA4vpq/o3+Tg5xE5HouzDPelo8OTzB/7sVsFHIFah1BI3PoIcbNBKNuMz34KU3ZQAs8LnYDutTKLtEXFOOhROidGochYXUG71guCH8byMo+tJ8ISzzNQCslvcbL2Xc3jlQwlsKtxB3bLJxs0pWbJ73MY4w2lDUBtXPmF3Qdw1n4CoWs09EJAxYU1ZvtwftTtfIEOV3YODIC5QzZ1zH6yDDvjPJ2WTLbIIXrsC00a0KM8aek8lHog9a/ypZKFZ+QEw5kWSVkp7hALM3jwxrSNF6gnf0Rnmw6V6MltZI+MhfSYsb0YyINvhQaiI0hyeeIEMSyZZfMRhDCKmg09ee/pkUD/d5lOQ0/Nb0fhdL4MCsR4X8YoG+OFgZ3D47Mvw9qpOw2m5SQonMVDJQFLH+qNgSqlcoJbqy0ElBK1eUHP9aHUyMVugxR8v383ernTsUhBja76w2lJ1d4Cd9Gfh0ASKO8ApnxCH4//R34u0DX5VIZHHQRZa3BoyjdsS+2FnEEcjZXYmT+O89+m0bjNqnMvkR82YKssUPI1DW+OwoE06TQX0jyOkFmGEFnkJEOa6ScnjiCRLc4T65ABbK2xKTo65ylS5zMY6/QmbNCoteoq9f9RelLyK6Ra3io8pjQemdyLBiHq+NySUK75dO7YxUuZJJswQ==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
class PhpMyAdminVersionCheck extends VNag {
protected $argSystemDir = null;
 
public function __construct() {
parent::__construct();
 
$this->registerExpectedStandardArguments('Vht');
 
$this->getHelpManager()->setPluginName('check_phpmyadmin_version');
$this->getHelpManager()->setVersion('1.0');
$this->getHelpManager()->setShortDescription('This plugin checks if a local phpMyAdmin system has the latest version installed.');
$this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
$this->getHelpManager()->setSyntax('$SCRIPTNAME$ [-d <directory>]');
$this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
 
// Individual (non-standard) arguments:
$this->addExpectedArgument($this->argSystemDir = new VNagArgument('d', 'directory', VNagArgument::VALUE_REQUIRED, 'phpmyadminPath', 'The local directory where your phpMyAdmin installation is located.'));
}
 
protected function get_phpmyadmin_version($path) {
$path = realpath($path) === false ? $path : realpath($path);
 
if (file_exists($file = "$path/libraries/classes/Config.php")) {
$cont = file_get_contents($file);
} else if (file_exists($file = "$path/libraries/Config.class.php")) { // older phpMyAdmin versions
$cont = file_get_contents($file);
} else {
throw new Exception("Cannot find the phpMyAdmin version information at $path");
}
 
if (!preg_match('@\$this->set\(\'PMA_VERSION\', \'(.*)\'\);@ismU', $cont, $m)) {
throw new Exception("Cannot parse the phpMyAdmin version information at $path");
}
 
return $m[1];
}
 
protected function cbRun($optional_args=array()) {
$system_dir = $this->argSystemDir->getValue();
if (empty($system_dir)) {
throw new Exception("Please specify the directory of the phpMyAdmin installation.");
}
$system_dir = realpath($system_dir) === false ? $system_dir : realpath($system_dir);
 
if (!is_dir($system_dir)) {
throw new Exception('Directory "'.$system_dir.'" not found.', false);
}
 
$version = $this->get_phpmyadmin_version($system_dir);
 
$cont = @file_get_contents('https://www.phpmyadmin.net/home_page/version.json'); // alternatively version.php
if (!$cont) {
throw new Exception('Cannot parse version from phpMyAdmin website. The plugin probably needs to be updated.', false);
}
 
$json = json_decode($cont, true);
$latest_version = $json['version'];
 
if ($version == $latest_version) {
$this->setStatus(VNag::STATUS_OK);
$this->setHeadline("Version $version (Latest version) at $system_dir", true);
} else {
$this->setStatus(VNag::STATUS_WARNING);
$this->setHeadline("Version $version is outdated (Latest version is $latest_version) at $system_dir", true);
}
}
}
/trunk/plugins/phpmyadmin_version/check_phpmyadmin_version
0,0 → 1,20
#!/usr/bin/php
<?php /* <ViaThinkSoftSignature>rFtb6jP+AsAXmTUE+8iu2pORGBWeXAckPLtN/B42PL9cH3hNjM52e2j//r0wnzjjX43mfs1DY9V0wIqnj3ZHyr1T2eahQBieE77aoPjXnrDo3q9zKYGXBn/HYCe/GSy7P5UHZr13+qg7vOtbRkShY1ocvDMChpOUqFeoK6XTHIrExtGy36mmD5BNnW5xGwlLscSGbq6KEmreyIfCA3K1NjHn6Hw1MmfdnglXGHzN7YpnjtW909aFmgYScJGaddwp29TNJBA8oDpxsOzLT5iskEq98OzZJnhwuMClSEWgKPIJVqQy4lIzKD+LgDaLFZwc2EM7wdIICpv8rYs9wADYn+zyIiCID5T6WziJRv9vc0jJKg9NGDowJehfKPSYVgPpPhGTztvovnoXr4GNOSKH0NxJF7q+vZxsiP9OsFJXWgtzdRG3pdxlNaT/KhraU/W+p27kgTz54iMhkkShx9EskOP5vFqhlNCuN4pcvKlB+N+pLxGLtHQ+N400aPD0WVP2oyS/1sblPpkWuuUookWSQK1cTBf60kYqx3BOkn3JUiDRVZgqvI/ipc4EEJLiYVdxHsKqu/kJoB1qYXXxOQFSRUZ7UZLkVvn+JZtW6nnK/81fOeRKE3VIV7x5ejR9T8tB+dqv4sCMmjjF2ehtevg94SMBSJjzPRcGp2pBdvvLBI83jZbxVAuUflLEE4BshNxIrTFkgO/HSczGd0426D3V8xfTii7e+VqX9JP3nmv57nsfwf4xrs2+cpZ568hhC9Z9N/aRswz8arsorgOTcb3uPe8fkkakoIqNY7Hn/3s4YLl4SO6f/RIiEUE+vw+mT+cRK5YL9uphb4WmgLldHT+SbLRJXL9HGGRS8QJQf42SwH0IeCX2IHFC5uge/j8vOT8IaJFuuZ+iZNuu85Dx/Xqy8+0xY/rWffR3cqIl6qsgeVC3aAPupPoC3ndb9R4VLCN/6N4RlY1IvePkYSgPV8W7ufroY9rAGneyB0y1uA+wfetqIcwxFlqxq2GgSVl/koBs6jaeN/15CmwSrp9Yi+VNotQZJFI+spIi45XM8dAgzIXNFia5VDJomy+NgvkvJf68De7UWxXo9WLebIMtWC6ShwmNvg/hcdwfk6tCE0DMUjtOVYWcJSAnwFTiiOR+YcJkTHA8qDL16QxfZBVzNJlj4SOFvdv7w3KK+JM5OjlWVoDy2zRIE8IK1uGe39YXEnZbRlWP9EHf1f239hhZ4z0/23Mj98bft2PSMcjWzioEDmzdCvba5lHBE5mrmXGjik/zQuypMXe4L8276RKA+Wc3HJ3pYyE66dHT2cLpAs8Sjg3KzcEAwA7N8eedyMnIh6Wj5oShDqp2XVQoWt7MaTY1mg==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__ . '/PhpMyAdminVersionCheck.class.php';
 
$job = new PhpMyAdminVersionCheck();
$job->run();
unset($job);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/phpmyadmin_version/icinga2.conf
0,0 → 1,48
// Put this file in /etc/icinga2/conf.d/...
 
// VNag - Nagios Framework for PHP
// Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
// Licensed under the terms of the Apache 2.0 license
//
// Revision 2018-07-15
 
object CheckCommand "vnag_phpmyadmin_version" {
command = [ "/daten/vnag/plugins/phpmyadmin_version/check_phpmyadmin_version" ]
 
arguments = {
"-d" = {
value = "$vnag_phpmyadmin_version_dir$"
description = "Location where the phpMyAdmin installation is located"
required = true
}
}
}
 
// Example usage:
//
// apply Service "example_website1_phpmyadmin_version" {
// import "generic-service"
// check_command = "vnag_phpmyadmin_version"
// vars = {
// vnag_phpmyadmin_version_dir = "/var/www/website1/phpmyadmin/"
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_website2_phpmyadmin_version" {
// import "generic-service"
// check_command = "vnag_phpmyadmin_version"
// vars = {
// vnag_phpmyadmin_version_dir = "/var/www/website2/phpmyadmin/"
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_website3_phpmyadmin_version" {
// import "generic-service"
// check_command = "vnag_phpmyadmin_version"
// vars = {
// vnag_phpmyadmin_version_dir = "/var/www/website3/phpmyadmin/"
// }
// assign where host.name == NodeName
// }
/trunk/plugins/roundcube_version/RoundcubeVersionCheck.class.php
0,0 → 1,78
<?php /* <ViaThinkSoftSignature>1BHpcBSx7ON/HUpCcUkKhSUoiYXQMQtnAdXX2iAlOl/JzKKg6SFnZOPnKWmR7wB3gptP+9uUjA6jE2DUc43XLKjhqhDCzZRlDPpTSxjfIz0b096R2o1AHchZq+IM/CoSWER0vlvFuA6Xw4XT5wT394u1Ndj49cBNf59F3cPnWO+vPK2PZwnKs7jgYAUssOErx5C47o2B1iYx5iWZu7TvW/8WKEKXBzHC0rvmT1qF0wvcyx6kQKoRENBHdZsRoVjDAuffY6YRXBiNfIcOWn4lu9hZqyWufxSJ3f18RTpul67YbcI5G+MNUqQmn6aDtf9NSiafiRLngQwU52ihlEHHTZWfAu4oKRWXzMHhgvrjel8B3a7nOl3iDUmvCVIw2tjGCCzeS9kTDEWBu+Uy6r8T5AjHkYcLRV2Icl4c4qQNQWt68VC2AVUIqIPpHqIITI4tluiY5YoQLiPqNgtI362fWzkMivY4Ybj2+G4llNd4OUCA3ob5jG3CoqNCOt0wtyDnXsMUGzV3114FR0TNYkI7SSaJsXZ5kMeUxh1Fq1axclrmL/ABRvmwpYl6OfJtNRTYM+YBh9NZndDDHOZaJkl31q8CqPzSbOX6YNeJx1u/qFPFl1y4LRW+KS9uT3xCSZKfik9gHSNBt/bGyytmBpJMSZcLB5Br/qB0A+IVNBdslvoJ02SDLyWLfC8/PffgedJCi1BbFJ3V6uPkTlAOiJTKYYB4CMXjlfByMMKZ6WzJR2KoT/yvn3ulOWU4tFK54p+2DTfSQWK+i7Jmw8klkRrFNLbUnBnoMSADYFaOEco/6SzCbaWUOWuwBCPk+HmmOTMLUrsGwiyXT8EKTeghRtKBb3F8RWVNFN8mW+yraq4a04JZfQQMXUwwaW7Uq9Z9gBsBSkzw/2kbKsqfj9TE3GuaNweD9yd3Pfy3j88F9Hx55AsNpF+nxk/3Q4RbiGtE5o7/lD2GG50Jbnvj/tMRxd5jAepzZHcs9SkxHNmGA0DfGHZuDQ53Yx2+KnQKFP3FJ7JKtn3WB6ia3KvafDxYqSFaZAiIT7B6Z/7cDIxQ2QJH6F7mh5UXcg06mtoBuHyEiyQnp8vW9ayyDMRR7VAYgjTu5RBLZ+9woEBB9/hZv3M79Vzrrvou6/Z2oyoVp2LcOBJlu5HZYClL56s0gXFaQ//7KN6mNB0mB+kfLOHw0Yy9tqh8HPASh51IaLBO1J7b+YErbRP4GSs5zjgcU0rOvBHlhcyOpYqm8xlXCtpNrwYfprWXxV7YZdTSGK7vlIq5tIK/C5nkrf4md7gIdzSQ2CI2wcTytO6uQWTuNlEm25bx7VJUdj+T+s7em9GLkXyMaI3nfgnU+gl8sr95AEoP+45X9A==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
class RoundcubeVersionCheck extends VNag {
protected $argSystemDir = null;
 
public function __construct() {
parent::__construct();
 
$this->registerExpectedStandardArguments('Vht');
 
$this->getHelpManager()->setPluginName('check_roundcube_version');
$this->getHelpManager()->setVersion('1.0');
$this->getHelpManager()->setShortDescription('This plugin checks if a local Roundcube Webmail system has the latest version installed.');
$this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
$this->getHelpManager()->setSyntax('$SCRIPTNAME$ [-d <directory>]');
$this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
 
// Individual (non-standard) arguments:
$this->addExpectedArgument($this->argSystemDir = new VNagArgument('d', 'directory', VNagArgument::VALUE_REQUIRED, 'roundcubePath', 'The local directory where your Roundcube installation is located.'));
}
 
protected function get_roundcube_version($path) {
$path = realpath($path) === false ? $path : realpath($path);
 
$cont = @file_get_contents("$path/program/lib/Roundcube/bootstrap.php");
if (!preg_match("@define\('RCUBE_VERSION', '(.*)'\);@ismU", $cont, $m)) {
throw new Exception("Cannot find version information at $path");
}
 
return $m[1];
}
 
protected function cbRun($optional_args=array()) {
$system_dir = $this->argSystemDir->getValue();
if (empty($system_dir)) {
throw new Exception("Please specify the directory of the Roundcube installation.");
}
$system_dir = realpath($system_dir) === false ? $system_dir : realpath($system_dir);
 
if (!is_dir($system_dir)) {
throw new Exception('Directory "'.$system_dir.'" not found.', false);
}
 
$version = $this->get_roundcube_version($system_dir);
 
$cont = @file_get_contents('https://roundcube.net/download/');
if (!preg_match_all('@https://github.com/roundcube/roundcubemail/releases/download/([^/]+)/@ismU', $cont, $m)) {
throw new Exception('Cannot parse version from Roundcube website. The plugin probably needs to be updated.', false);
}
 
$latest_version = $m[1][0];
 
if (in_array($version, $m[1])) {
if ($version === $latest_version) {
$this->setStatus(VNag::STATUS_OK);
$this->setHeadline("Version $version (Latest Stable version) at $system_dir", true);
} else {
$this->setStatus(VNag::STATUS_OK);
$this->setHeadline("Version $version (Old Stable / LTS version; latest version is $latest_version) at $system_dir", true);
}
} else {
$this->setStatus(VNag::STATUS_WARNING);
$this->setHeadline("Version $version is outdated (Latest version is $latest_version) at $system_dir", true);
}
}
}
 
/trunk/plugins/roundcube_version/check_roundcube_version
0,0 → 1,20
#!/usr/bin/php
<?php /* <ViaThinkSoftSignature>L1MnUb3Xkc3wOlB1E7K6789Ibm1YZDKX/5BoPgDbdDb+X3d0MSj/nVfVHvhEkhqyO1KoQrXAp9+SNexpdSj90bkR72eAoEdwBGJSEDmrqaVerSsdPBIGdIT2sgA60hcodNHuV7LBmxLDioooX6FzyWxfplL/cYBfRZPAbzV7/Pl8vggZuKVUvd22zaYiyUF59qaZfO8H4DiR4s7B/OPfXDXTMbwN54Jy2SibYiBDzEYPkrakdebzht2XSnjs308we9v0MJ9JDFJruBD/SnTQFDVEicirIJwfswcYL0UoSE0V+dbfilWzbREPIb7uUZOe3FxJ6QGZbQU8eutjsHbLjBZ05whU8icmcuY/GviWoJn7x7L0sOZD+U3xkCbVQSqzOtI22kkY+qckNz6IaCTJK0K8honEUQrHkpSOyvH029ioIzz40o5X5OaOGAXOz7hnS4wj0CbRs95e/29aY26f1gV2nllkfXmaK0D8ghuxeUXI4fN7479d4rdOC8QkiuXKSUFXvbPXlK99bXtAr8p9Y2Ea2t8pYQD8GTBgVUXuqnOlx2XLNShLeDhXXmhrPztXKpQe4hb15JqJF49tA8E8RwybZEH3JodntS+S7COOp1qKMMLpZD051KeeJ3QfJ4aJzHD4Iu+AA2uvR+jY2fqiosDLyzPDu6l3jHKJ+1Qy1KsZpWNXQ7MGxFSXRqswLxCE/LUDDE66B1dR3psyCVF7XVT/Al6lvn/3c+qjy/ydwb65SYTCZNTvGK64VabmwzP2qiiBAilpxOT6VZ2JDV4nfNMIR2Iqf8U2wiDOuAtV0wB3L4Vt2RV0tJETIqe6uizGrXEInLi3d/hwCTObty/BriV/6gbzJ/sQrK4s+oNv3RJcvaCv49aGe0hnWNoZ9TozcDNr14Kl5HsZSA7lz9WkiLNJ+B+Eaq4U7drKFRmSw5PWgbs3EqG1bo9kQ5wt9Wqpa7dlzDhkypCfjEIPcz+wCXec+/cYdTDrMc3Eu/YlaPpYv82YUW1Ab6b9n3e6vbLehkUzGpBK4N7+Q0GUqDq+mSq33XoJgubo4ES+bNHZGojf8TDZn4H9gcwv5IRU0D8rM97Q2bpaYste1EDqH8gWiazlaYlMpG2iuPieUzaD89tgS7acSD1Zd9bJpw9EN+OgsyYlukulhc6qVyw24q+PPp9Ym9a9MI8kOLI58ShWeoDNO9e/PVghds1AmDuf3CX3kz8rfv8wL3nqBLlKwqf8Dr6qP6wvx7+lpbBPa4QbVFTjg6TSGxoWQFUyMUjQJBnlckpP80x3Gq6FiH0MYvRdrJZ9Qzr5z58WbNUhezuLKWrvDizYQja41k/EC29Q1addLTG7bDHne8CjjDRSoFHYPQ==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__ . '/RoundcubeVersionCheck.class.php';
 
$job = new RoundcubeVersionCheck();
$job->run();
unset($job);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/roundcube_version/icinga2.conf
0,0 → 1,48
// Put this file in /etc/icinga2/conf.d/...
 
// VNag - Nagios Framework for PHP
// Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
// Licensed under the terms of the Apache 2.0 license
//
// Revision 2018-07-15
 
object CheckCommand "vnag_roundcube_version" {
command = [ "/daten/vnag/plugins/roundcube_version/check_roundcube_version" ]
 
arguments = {
"-d" = {
value = "$vnag_roundcube_version_dir$"
description = "Location where the Roundcube installation is located"
required = true
}
}
}
 
// Example usage:
//
// apply Service "example_website1_roundcube_version" {
// import "generic-service"
// check_command = "vnag_roundcube_version"
// vars = {
// vnag_roundcube_version_dir = "/var/www/website1/roundcube/"
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_website2_roundcube_version" {
// import "generic-service"
// check_command = "vnag_roundcube_version"
// vars = {
// vnag_roundcube_version_dir = "/var/www/website2/roundcube/"
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_website3_roundcube_version" {
// import "generic-service"
// check_command = "vnag_roundcube_version"
// vars = {
// vnag_roundcube_version_dir = "/var/www/website3/roundcube/"
// }
// assign where host.name == NodeName
// }
/trunk/plugins/smart/SmartCheck.class.php
0,0 → 1,142
<?php /* <ViaThinkSoftSignature>JzjmNSphjJTRHMsIRHh892nocNxwZ2Es+ZcviS31H/rsieUvZmhp9cok7T2tEye/QwVbEbouz4zSVd9vP3Pvq37NJoqHC6s0zttRWeBrXKqkBpJnucsuT1M+OTkxdxu+CvXupKWifcXjUpQF+yxg+rPji/oaF5V8r4BZK7/GgZUyvovpuXSn2e0w91PtkrE7j9Weq8LS1SqcYeTh4AeozQC+GjWrrzzW6w90hDM1b4HSp+S5KcBQOTRY1h1umJp41XNeYb7/sPkmCsIbpf4YuzUFg4v7q9epYH/qwnfRI3Ll0jrFNYdGHFbgPGApmNkklNf7hSpWMAB1LaUh/4i/gkxceyHA8xt9i2pdHJIRiHoxzUFyIXevst0GOneUoeEUdLAyG3xCYxuai85ZvzeffkKQCVbEkQu/vitQUW6JiE3yeOMJFF9mEwPbHFC7uYEpnbV98FEsegNrxdM8vscinKmr/cGg/P2j+BjPVT+Uag+7ps5xxcmSHFIHZuD0VoKnyyDAyzOs8YhloJq0P8ovBTcJyvmj4Qzcs2UaM4WKmkFbFJhos2DxFxoPfh+DfiLVQJaO57npZOkbjX86+ann5OjkgJRgMDc4EFbfApfK1t4L57FTNJwEWIlmUl2X5k0LOXiLl0ShFGgpqfAIUvB+K7TQbEh3wRdqSuUhTigUqL/aEFygygueEPh2DhIPc//QENU22fSMcxT+Ud+uNJWgXqxCg6NxjyshWTNwvIFWX14LtqauL80TUhXnYZZVtq4tbCNqb3DAxIvqK+F1aTbgQnb/JIq+4ntHjR9t2Jp22zQ+EEzdgIabG9YRfJNYLggwgUFrlmmFht0sVJVCl4dLPo/CuK6VVTIj1PLSIKpa0mnt+cadUMrJVY1kogJHCmyzLpiwj4sff483YaH5gcOqAdJ1NlvnDJvhxZLV4JSIvuk8dGCdcuaa2HJfoVOxBFUguXB5wHsgTvOT7Ia8WpqbF6SJDfH2YqoUsAiifCUxi1C/NHffQ3mZc4ko7nzdTVHJgtfaPT1kkFscH2ZV6GZzUdJx0wcSr9e7d2zDCElP7R1rF01aiHCGlMOfdC4GnzxYH5MCgwBL/GNMN9qJmBK4sDFwJ6PiuJUlz20NlVlm/rwV0SfVaMHMtDZ7/L+ynva8W13SfsQeYhWoJxH8Um0dlvf5DG+Aq4mzMbCShHxG9zIrNSFfmYrKuh5ldot+/9FN6b4WTP7Ej1D0l55+1fcwBrXwxl8w9+awryEhXzuRtxuewnkNopqv+U3SEPlqK5nyZt8GwQZpqw1DzdGiA7jY7yAx/fTMeMs4ypVpxQJzt3Sct/BUkKHSkhSY0UrHyP2k4k29VGhwaAqZHBChglawvw==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-17
*/
 
declare(ticks=1);
 
class SmartCheck extends VNag {
public function __construct() {
parent::__construct();
 
if ($this->is_http_mode()) {
// Don't allow the standard arguments via $_REQUEST
$this->registerExpectedStandardArguments('');
} else {
$this->registerExpectedStandardArguments('Vhtv');
}
 
$this->getHelpManager()->setPluginName('vnag_smart');
$this->getHelpManager()->setVersion('1.0');
$this->getHelpManager()->setShortDescription('This plugin checks the contents of the SMART data and warns when a harddisk has failed.');
$this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
$this->getHelpManager()->setSyntax('$SCRIPTNAME$ (no additional arguments expected)');
$this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
}
 
private function check_smart($dev) {
if (!`which which`) {
throw new VNagException("Program 'which' is not installed on your system");
}
 
if (!`which smartctl`) {
throw new VNagException("Program 'smartctl' (usually included in package smartmontools) is not installed on your system");
}
 
if (!`sudo cat /proc/cpuinfo`) {
// To make this work, please run "visudo" and add the following line:
// nagios ALL=NOPASSWD: /usr/sbin/smartctl
throw new VNagException("You don't have SUDO privileges. Please run 'visudo' and allow the command /usr/sbin/smartctl for user ".get_current_user().".");
}
 
unset($out);
exec('sudo smartctl --all '.escapeshellarg($dev), $out, $code);
$cont = implode("\n", $out);
 
$msg = array();
$status = -1;
 
if (stripos($cont, 'device lacks SMART capability') !== false) {
// At my system (Debian 9), I get exit code 4 (which is not fully accurate)
$msg[] = 'Device lacks SMART capability';
#$status = VNag::STATUS_UNKNOWN;
} else if ($code == 0) {
$status = VNag::STATUS_OK;
} else {
if ($code & 1) {
throw new Exception("smartctl reports 'command line did not parse' (code $code).");
}
if ($code & 2) {
$msg[] = "Device open failed. It is either completely defective, or in low-power mode.";
$status = max($status, VNag::STATUS_CRITICAL);
}
if ($code & 4) {
$msg[] = "SMART command failed or checksum is wrong.";
$status = max($status, VNag::STATUS_WARNING);
}
if ($code & 8) {
$msg[] = "SMART status returns 'DISK FAILING'";
$status = max($status, VNag::STATUS_CRITICAL);
}
if ($code & 16) {
$msg[] = "SMART found prefail attributes below threshold";
$status = max($status, VNag::STATUS_WARNING);
}
if ($code & 32) {
$msg[] = "SMART status is 'OK' but usage/prefail attributes have been below threshold in the past.";
$status = max($status, VNag::STATUS_WARNING);
}
if ($code & 64) {
$msg[] = "The device error log contains records of errors.";
$status = max($status, VNag::STATUS_WARNING);
}
if ($code & 128) {
$msg[] = "The self-test logs contains records of errors.";
$status = max($status, VNag::STATUS_WARNING);
}
}
 
$messages = implode(", ", $msg);
if ($messages != '') $messages = ": $messages";
 
if ($status == VNag::STATUS_CRITICAL) {
$this->addVerboseMessage("$dev (Critical)$messages", VNag::VERBOSITY_SUMMARY);
} else if ($status == VNag::STATUS_WARNING) {
$this->addVerboseMessage("$dev (Warning)$messages", VNag::VERBOSITY_SUMMARY);
} else if ($status == VNag::STATUS_OK) {
$this->addVerboseMessage("$dev (OK)$messages", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
} else {
$status = VNag::STATUS_UNKNOWN;
$this->addVerboseMessage("$dev (Unknown)$messages", VNag::VERBOSITY_SUMMARY);
}
$this->setStatus($status);
return $status;
}
 
protected function cbRun() {
$devices = array();
$devices = array_merge($devices, glob('/dev/sd?'));
$devices = array_merge($devices, glob('/dev/hd?'));
 
$count_total = 0;
$count_ok = 0;
$count_warning = 0;
$count_critical = 0;
$count_unknown = 0;
foreach ($devices as $dev) {
$count_total++;
switch ($this->check_smart($dev)) {
case VNag::STATUS_OK:
$count_ok++;
break;
case VNag::STATUS_WARNING:
$count_warning++;
break;
case VNag::STATUS_CRITICAL:
$count_critical++;
break;
case VNag::STATUS_UNKNOWN:
$count_unknown++;
break;
}
}
 
$this->setHeadline(sprintf('Checked %d drives (%d OK, %d warning, %d critical, %d unknown)', $count_total, $count_ok, $count_warning, $count_critical, $count_unknown));
}
}
/trunk/plugins/smart/check_smart
0,0 → 1,20
#!/usr/bin/php
<?php /* <ViaThinkSoftSignature>PlZYWxINdIanFYFeUVDsTLMMxMM/raUv6IV5svu+EWfGtNMge4jicM8OwhfxJ+9xJfrw4BanWArk7PzkBD0GsT/nFZLHpRgXuMsEk7YPBlk2YxUEDkTkJeGsSy6wd/FhoHPfHlPrGveBymybvsOWlcF/bbvDJOcKoj5oDtflE2kAIg14xlKvJcy6X01iOtceueNh9KP4/PdQ+2fUGxEssGiz1MjgDjcA1teXlWtBZDlthMe6MhLpp9YPiu+13JkF5BUfZWhZqjmMpr2hYl8sz7CS6DvZxJUJIRci64qUZEdKcIljDhgCFq2m0FE9oPCNJwdX5/9bLk/lqpxjXMc0rz37TT/+Zf8i370I5EIepgzjqx+Xrut7aNyQOZ5173sKIPJDponDQToTGK30W3ZOZHWo+101+GDANM3v/l1Xk/k3XBEYBRKjYZmryGNd+9jn/byd8NLhQOLol5l34fGL6fBF1AE3BozqtqGqitKMjbnEs4grFssYb4ZQ1ynnFKPeXsYrg/0G9/Uxiv85vpPDBDujhaSbo0mdEBfN+icfbwekeWNv4Ldu+0iUhsVt/YXQ+cJenNreAM61L1KuWvC+WAbr5wBRz7z1QB0UUZ7+CeeLpxf5+PKafmiXQGPVPfhN7oiYTq3OCBWPpb4iaWeFgkJgW23y7Ydx+u89g8NAoMu8QEdxNe5hLtlpoE5yQ57aAArynICQhpCLT0sVVvq+sIl3Z9u2aPVfazsl1CPHZRXR9o+csaSp+rOU+t4lo6DzODIJfYiZ7NzO5IDR2J/C+yPzIWzDiOUG/FWbuBAofpqYvJBYzIWFY+AYxEGWG2NclTgkzd9qKfOf/CChNQpGQdvV2eAhiAN2296MG1FYdtA0N+XaS7M/Irujgcur8mWowzrz8osytTpW0+4PsT+KccuMyWwAjMUBmC18ui2a92eYs5ocXs+AmyFiknf1LvgfLE5ffa9MqU0yJZsJyxotN4ehpyaOHPx7pbxBhmiavMUPfWqPNwkG+JsqhjQAAgfQtBDPLxyk4eamnjclq6XuL+LW6z8SUnUtfNzMIdSKk6e1XdKYC5ToBfxK6TKDPg4FjhboIflD9IFG1aPPW/f3KbT2WgczpD1trJ07LSFMPn6eN0gCht2nys5n8jE5/yGVDwyF+1sMuXCCEx/2gdBGBqyL52Ao76cCD9G9jxG+cFcJN54+hQS7UQX0SV8oJy1GoKOfIkH+8QOzSx97oySFw4LWAPcNQEUhkx4sYmXD1iAnDFqp7hM0BLvSxUdprt6EYxoNH6mj4272BvCulaqM/JEvObB3/YvpbiKVTBZEyPrwJE4CXfzV4lGgLS+qs2+Zvt4NOaihB5iNiGetY+2T0w==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__.'/SmartCheck.class.php';
 
$job = new SmartCheck();
$job->run();
unset($job);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/smart/icinga2.conf
0,0 → 1,29
// Put this file in /etc/icinga2/conf.d/...
 
// VNag - Nagios Framework for PHP
// Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
// Licensed under the terms of the Apache 2.0 license
//
// Revision 2018-07-15
 
object CheckCommand "vnag_smart" {
command = [ "/daten/vnag/plugins/smart/check_smart" ]
 
arguments = {
"-v" = {
set_if = "$vnag_smart_verbose$"
description = "Additionally list drives which are OK, not just the drives which have failed."
}
}
}
 
// Example usage:
//
// apply Service "example_smart" {
// import "generic-service"
// check_command = "vnag_smart"
// vars = {
// vnag_smart_verbose = false
// }
// assign where host.name == NodeName
// }
/trunk/plugins/virtual_mem/VirtualMemCheck.class.php
0,0 → 1,64
<?php /* <ViaThinkSoftSignature>qMJiodDpZAq5lmMr1YTFAzBz7y3WUrxNn6+gko5VdixCfUQEjrRySixRs61b8d1N1MKEHjaL2mwgMYT7TsOisNeiTad8iUe4fDBzR7XnyX1LbvmOCDMbvRHwLR/LBf+N9Rkc3FwU0xmRHLpi5zJ2wwLCGwiurIVyXKoAUuYda8LIuJsg9XyfHiNFoJz91WnLuK8FleyiTF7timGeMFMP/FYnIBmuBjWnG5kGk79naWFLML386W/abe5VllqfeQMFGkLSBFlExWb5V6qaA/BO+0jheB2LOh6xNMkOEYvCdkKHWDpbdVG/W3gRsnE7cVJV7fKkBGt3nh89CS0XLswUDH3RWA/NCGBj+tc/QcIdFTezu4QSFaUO63OOPusEVrZZG80vUl5vKIPtKakVJrix/EYzOBRC6fNRIakkB/q8k1UZD27Fa4ySQJgedJm6hIa7q+3Ln9MX6083Cyeu5nMMqQy7emY9q5g6EPJugxO1GsxVegHN800coIlEipLCDANvr/+jOOb/K9jf0j4+RhNUdSmXV3HTLvEKOnL6SsPCtFlo9wKOwUBfqrlBBTBV3A4DLtTD1Oc/6wJKDPIf04yigCxw+Nn2oK9TZGH8KHXscTPxru6BIn07hZq9oGO5EyW2K2AISY4OjFGaMAuns2jAQHPacRWWvc9gp67nk9TfPFStZYLWkSfzeSaAn1NEBncAriGWNOxGnpbXAXKZ8EiCQNHrqPnDgObgkgx5/PxhxFoacVUzl9CWZWSiKmbbppomlVDWuPUqJx16BNOvWu6H2oWq+sYav1cvTnZ4dpBKiMLNHLma8k6sA6UdSxuRujTSFll9cCVrDlj4WMSYJfufXv4pD3Qp5SQLlXj70ioM5jAx04sRSNQg/BDPcdiTzOXGx64B/m0gDb6x4CWVBrB0MMml4u3R8NFsCQpmDTAWVICAXdV5nNa8LcXrB5JQz6R9UFau1JuVN7ES6YbEv1og+Jh3DzY5iumbVWUugAppBV7MdgHN50vIwFC3YrVIfUjSyC4nnr3JZ4uuQfqiPY8NvY3RQ5J7avSt7Z67I5lz5swwrDro3iGk8a0tMGHWg8BDYwijuedici0fFpu8oK1ss7Kmwpvuti9bk4DvYH4D8gUjN3s8H0fE3D+v6sPNg3FQXs64Ob8jptqEUKMRfzXuIYbI89WgLV0TADxTm8kmDAJKOYW9xBQqdJh3UYo0Rwwkd7X3hvAUi8JojHWlizNJsqWm+6wv+HfX4105MVNXbANk1w4Go5fJ2xSjXJdKQESoNjhipKgSk7mYbRcZON+QvLaHROFrQ/EK2lAmcDcJUKf+fK0JZGTm7+2xeLwE65jAvwtD40Dkw9JNy4AVo8k02w==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-18
*/
 
declare(ticks=1);
 
define('OUTPUT_UOM', 'GB');
define('ROUND_TO', 0);
 
class VirtualMemCheck extends VNag {
public function __construct() {
parent::__construct();
 
$this->registerExpectedStandardArguments('Vhtwc');
 
$this->getHelpManager()->setPluginName('check_virtual_mem');
$this->getHelpManager()->setVersion('1.0');
$this->getHelpManager()->setShortDescription('This plugin checks the amount of free virtual memory (real memory + swap combined).');
$this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
$this->getHelpManager()->setSyntax('$SCRIPTNAME$ [-w freeMemKB|%] [-c freeMemKB|%]');
$this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
 
// When the user writes "-w 10GB" then he actually means "-w 10GB:~" or "-w @~:10GB", so these commands allow this notation:
$this->warningSingleValueRangeBehaviors[0] = self::SINGLEVALUE_RANGE_VAL_LT_X_BAD;
$this->criticalSingleValueRangeBehaviors[0] = self::SINGLEVALUE_RANGE_VAL_LT_X_BAD;
}
 
private function getMemAttr($attrName) {
$cont = file_get_contents('/proc/meminfo');
preg_match('@^'.preg_quote($attrName,'@').':\s+(\d+)\s+kB$@ismU', $cont, $m);
return $m[1];
}
 
protected function cbRun($optional_args=array()) {
if (!file_exists('/proc/meminfo')) {
throw new VNagException("Cannot find /proc/meminfo");
}
 
$totalKB = $this->getMemAttr('MemTotal') + $this->getMemAttr('SwapTotal');
$freeKB = $this->getMemAttr('MemFree') + $this->getMemAttr('SwapFree');
$freePercent = $freeKB/$totalKB*100;
 
$this->checkAgainstWarningRange( array($freeKB.'KB', $freePercent.'%'), false, true, 0);
$this->checkAgainstCriticalRange(array($freeKB.'KB', $freePercent.'%'), false, true, 0);
 
$m = (new VNagValueUomPair($freeKB.'KB'));
$m->roundTo = ROUND_TO;
$freeKB = $m->normalize(OUTPUT_UOM);
 
$m = (new VNagValueUomPair($totalKB.'KB'));
$m->roundTo = ROUND_TO;
$totalKB = $m->normalize(OUTPUT_UOM);
 
$msg = "$freeKB free of $totalKB (".round($freePercent,ROUND_TO)."% free)";
$this->setHeadline($msg);
}
}
/trunk/plugins/virtual_mem/check_virtual_mem
0,0 → 1,20
#!/usr/bin/php
<?php /* <ViaThinkSoftSignature>1tZ2zhsNDzqmhiH3ABR/vEURfI5EhJ84vcNAwcQE/dQg14SjH8n9xfN3LhkIj0cnO7Et2VtRIwFVI0i/px+Ll7nNgMT663r2w35BVBU4XDnA/ndomCR0P1JU8aJd6AsB72Ywhc+c9C/YsOEtfEVwZrfjmhv80S2aBIglBlcJ4dFKTpkkdECH1sMaV5xvuT1ISFCf9v4w0XO9m7r4CMxYHbzDkhDCM9mt5WjLqOsTAtpGiNtwpaRpa2T8ruSF3fsXwBqGBpw+vQXgV/Znka8QGeTzrmlH/sbnFhyW7VFeoYCO49o+d61eJzovRExmzPR9vvhmKSoZcFPi5hAt3xh2OVmtuMTP2946C62UVsSZSI+AHCIjyu9Oi9lrZnGxrupqGp389RaWeuvv8xgh+PcHVMU1+vsYNYh4f8lWUNzXUJLodvERrdKGt9kSH+4FQk9oiBFfz+TbiMlGl7lMgp97cafEz2JvupkUG30cH+VzQNNDsCNgYdwKs5+d7m9FoGfnpjXm6oPRjRvvA2nTwKQaOFp6N8UlIbt5fnpnqLjHu71aoARG/uhVjkxKGmMboMHwjdmCBMoeOgqJN0Lt043rjoAN8bJhf2cRpQtlcNO6ZdTOr1tyn3HhkTMj3m9mEZn1CYYGnGisUYr+se5bmq6Ki7Fo5DdGe1d8Gg1NVq4zBzhCSj5rR2ouQiFgOkEk8yDZWhpI5uhRpdytEqeF+H3SXRkso/A1qqdpr9lSz+FnROyJaw2afEC4MwRE0+GrVsnoxV/Ygutc4O45qTmZ/JRswSb/YsLVBimRtujyHrKB03WutGC4SQIMRYJ22JdfZVys5HfH5i7GPSrDr4W11wEuIuAmO8VALaB2/+waSvaBxNoU0j3xAq/M8X96yexL6jOUUEASmDmEboK21bLb0coNQ0YT0zWkm/OUo+a92k3mN+YoueEOumxQMgpHOBYfqYETAq/onkbnPaIKYUdqsmClJ6OWcaBZBlR/V8+Xzrp3Q+PDEVFanz/wuhagkz5ar8wEE/MXsyTk+9CsKY2WxIT+o32+kJRAgP/2Tt0rUJDWbD9IAyTAT5Sd2xLdsO7GLgnAIV32Z/AE7fCfcSRsxRmpU6B6zskOlOBto3ij9sKui8F5/QVUjmdSo698jMky0nDEnpXCRzdjcRYEOGbk1Ybf6RwMR5GLMfXYtHRcaMoH4EDLxWnwoGbdYXe6sIRtfmgGL7G0fj8JiidekWqUGZGyU6ucbtrp8vFkHY5JgCa7+lw0sH22qeozrDb3chTSgqvXFkdGOzqXUPpO1RgUx5nCpFOgPm2TrfE+HittOIW34NlIwoH6i9kkQ/FyqRJwLWtla4kuGe/A41RtEbutt0FmZQ==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-18
*/
 
declare(ticks=1);
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__ . '/VirtualMemCheck.class.php';
 
$job = new VirtualMemCheck();
$job->run();
unset($job);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/virtual_mem/icinga2.conf
0,0 → 1,36
// Put this file in /etc/icinga2/conf.d/...
 
// VNag - Nagios Framework for PHP
// Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
// Licensed under the terms of the Apache 2.0 license
//
// Revision 2018-07-15
 
object CheckCommand "vnag_virtual_mem" {
command = [ "/daten/vnag/plugins/virtual_mem/check_virtual_mem" ]
 
arguments = {
"-w" = {
value = "$vnag_virtual_mem_warn$"
description = "absoluteKB or relative% (Warning range)"
}
"-c" = {
value = "$vnag_virtual_mem_crit$"
description = "absoluteKB or relative% (Critical range)"
}
}
}
 
// Example usage:
//
// apply Service "example_server1_virtual_mem" {
// import "generic-service"
// check_command = "vnag_virtual_mem"
//
// vars = {
// vnag_virtual_mem_warn = "10GB"
// vnag_virtual_mem_crit = "4GB"
// }
//
// assign where host.name == NodeName
// }
/trunk/plugins/webreader/VNagWebReader.class.php
0,0 → 1,83
<?php /* <ViaThinkSoftSignature>A/Ae4mLugX8aWi3kU6+IP3v8vJqavUp5B0oOzj6LG/H28D/deFDPma4ukxYN933EN3jWEdDAPnJYHnAnicrW6X037PjLCDDfCFSI0Ag7uERGhacn0+jjtD8HlUp1Rx1vmwGbMVnhwbZaTHb1579ASAEE+s06LC21zzaAovhaQbe+zQpSMyUijBU7QuiOT93DHZjRsxmZe5RUU8DIQ55hYj70k3iiVkN7QKss700e6dtfctedZxSThXIjFLWgv/8PAQNVsIzpb/T9EbqiibvsWDWGn30pVjDsGLltOM8+iakOwaY5/0lO5DEfLUuChV1d2CZpzvH8QHD8iG2ur4i4JJyJ953yzvKO5ewFsOFKupHAR1QyTMYGyd+wtBLsiRYw7IJgsvkF7Z3XUzuwoVhnsDReF9jH2IG6R1rH0CuOAMspnD+PravAeFCSOJY2XVN0eJZmSNZFh77U8mIHTooJSCwBJDzgxT3RrRs23mUrvLm3IDPvN9QHI/tK1YaTGDwQkc9ToO5H5jQwvz90zH0ovu64QtGVVlBqQ0ImoBIs1trB4cPsLKTQwCNKrSPbbeUq80p92o1kVLVC5IWMma6WIwI1t/8YGRdEDhHtxtI81LevAqTKoiA0/YxKk7fHeYb0Icl+v7VFTcWOluoM7E3In9mvRnnXXW3yUlT1/OquygQxkJ75xXPQXRHAjE5m5lMNePySNZ5HGdwvfJjUMH5hRkiMlIcTz2uLNXWo04DCAksS45frCDdsLGik9Djwfii1BQHspudV77QBAWw76StXbeThv8k4JXG/3+pANiUp+AMn9RccVrvcRUuJEyJkRxxlMjFmA8zjfGWRlhd39hotSf1a29SkECiPLbYWO95D3Um1PGVaT4IqNAC/I+Y3Vt+Cu2I60cB1nKIeZosMHjdR1bCrib9DNbT2Pv30p4BnfLYE4hR8WvUpkEgQZRnTYhMQIa9vdMfUo6tEYyvu2xMI8LD22KsgZh+IYQtsfBMtfs9UBXGVBOg6W6BSpCivBUqT+M5PDz3VAB39dB+qaWs1wgkhAN/7/Uqo4DyjheoIYVzChgyX8p/zC9m62ppAhwr4aIrEdtrCsiI1SpBWAeCIKMzXU1FdY96f+EgnJzCD5ViENvkx58HiLUURl4SLYX/YYinVn2m2yS4mIk02S5LEU6tgGjnDdc82KGQLDDQKjU5w9/xz08SIRqwn5PpGeisv3EYoj/9KandHgAU9fDp2qkurm42hGkly4avVs7H58xVrzXW0pP2NW/fJEUOoYqSWZp9bE+Jgr7Y2etBdov2y0kNYaeil4VKsM/m/cIFBs9RmsGmSaBamsj0WMrCuiM9jTDZcj2q0wqvd/yRoIuMnyQ==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
class VNagWebReader extends VNag {
protected $argUrl = null;
protected $argId = null;
protected $argBasicAuth = null;
protected $argPassword = null;
protected $argSignPubKey = null;
 
public function __construct() {
parent::__construct();
 
if ($this->is_http_mode()) {
// Don't allow the standard arguments via $_REQUEST
$this->registerExpectedStandardArguments('');
} else {
$this->registerExpectedStandardArguments('Vht');
}
$this->addExpectedArgument($this->argUrl = new VNagArgument('u', 'url', VNagArgument::VALUE_REQUIRED, 'url', 'The URI of the page that contains an embedded machine readable VNag output', null));
$this->addExpectedArgument($this->argId = new VNagArgument('i', 'id', VNagArgument::VALUE_REQUIRED, 'id', 'The ID (serial or individual name) of the embedded Nagios output. Usually "0" if only one monitor is used without individual names.', '0'));
$this->addExpectedArgument($this->argBasicAuth = new VNagArgument('b', 'basicAuth', VNagArgument::VALUE_REQUIRED, 'username:password', 'In case the target website requires Basic Auth, please pass username and password, divided by double-colon, into this argument.', null));
$this->addExpectedArgument($this->argPassword = new VNagArgument('p', 'password', VNagArgument::VALUE_REQUIRED, 'password', 'In case the machine readable VNag output is encrypted, enter the password here.', null));
$this->addExpectedArgument($this->argSignPubKey = new VNagArgument('k', 'signPubKey', VNagArgument::VALUE_REQUIRED, 'pemFile', 'In case the machine readable VNag output is signed, enter the filename of the public key (PEM) file here, to verify the signature of the output.', null));
 
$this->getHelpManager()->setPluginName('vnag_webreader');
$this->getHelpManager()->setVersion('1.0');
$this->getHelpManager()->setShortDescription('This plugin reads embedded machine readable VNag output from a website and converts it into a Nagios compatible output format.');
$this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
$this->getHelpManager()->setSyntax('$SCRIPTNAME$ -u <url> [-i <id>] [-b <username>:<password>] [-k pubKeyFile] [-p <password>]');
$this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
}
 
protected function cbRun() {
$this->argUrl->require();
$this->argId->require();
 
$url = $this->argUrl->getValue();
$this->id = $this->argId->getValue(); // default is '0', so we do not need to check for available()
if ($this->argPassword->available()) $this->password_in = $this->argPassword->getValue();
if ($this->argSignPubKey->available()) $this->pubkey = $this->argSignPubKey->getValue();
 
$options = array(
'http' => array(
'method' => 'GET',
'header' =>
sprintf("Authorization: Basic %s\r\n", base64_encode($this->argBasicAuth->getValue())).
sprintf("User-Agent: PHP/%s Vag/%s\r\n", phpversion(), self::VNAG_VERSION)
)
);
$context = stream_context_create($options);
$cont = file_get_contents($url, false, $context);
if (!$cont) throw new VNagException("Cannot access $url");
 
$data = $this->readInvisibleHTML($cont);
 
if (!$data) throw new VNagInvalidArgumentException("No monitor with ID \"$this->id\" found at URL $url");
 
if (isset($data['text'])) {
$this->setHeadline("Special content delivered from the web monitor (see verbose info)");
$this->addVerboseMessage($data['text'], VNag::VERBOSITY_SUMMARY); // VERBOSE_SUMMARY is *our* verbosity, not the verbosity of the target monitor
} else {
foreach ($data['performance_data'] as $perfdata) {
$this->addPerformanceData(VNagPerformanceData::createByString($perfdata));
}
 
$this->setHeadline($data['headline']);
$this->addVerboseMessage($data['verbose_info'], VNag::VERBOSITY_SUMMARY); // VERBOSE_SUMMARY is *our* verbosity, not the verbosity of the target monitor
}
 
$this->setStatus($data['status'], true);
}
}
/trunk/plugins/webreader/icinga2.conf
0,0 → 1,46
// Put this file in /etc/icinga2/conf.d/...
 
// VNag - Nagios Framework for PHP
// Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
// Licensed under the terms of the Apache 2.0 license
//
// Revision 2018-07-15
 
object CheckCommand "vnag_webreader" {
command = [ "/daten/vnag/plugins/webreader/vnag_webreader" ]
 
arguments = {
"-u" = {
value = "$vnag_webreader_url$"
description = "The URI of the page that contains an embedded machine readable VNag output"
required = true
}
"-i" = {
value = "$vnag_webreader_id$"
description = "The ID (serial or individual name) of the embedded Nagios output. Usually '0' if only one monitor is used without individual names"
}
"-b" = {
value = "$vnag_webreader_basicAuth$"
description = "In case the target website requires Basic Auth, please pass username and password, divided by double-colon, into this argument"
}
"-p" = {
value = "$vnag_webreader_password$"
description = "In case the machine readable VNag output is encrypted, enter the password here"
}
"-k" = {
value = "$vnag_webreader_signPubKey$"
description = "In case the machine readable VNag output is signed, enter the filename of the public key (PEM) file here, to verify the signature of the output"
}
}
}
 
// Example usage:
//
// apply Service "example_remote_ipfm" {
// import "generic-service"
// check_command = "vnag_webreader"
// vars = {
// vnag_webreader_url = "https://www.example.com/vnag/ipfm/"
// }
// assign where host.name == NodeName
// }
/trunk/plugins/webreader/vnag_webreader
0,0 → 1,20
#!/usr/bin/php
<?php /* <ViaThinkSoftSignature>fGSssQ5WiH9LfwSUqhiDzyZMfWbfjEBnlT8HfyBUcHSXiwnI/ni/dG14gKW0iq5H6RvGE5C3Zdh4yFghcT4M/RjhDETWCzpD0UgGMpXOaHCT4vmVOIfm+RMC4DR5aZparl4BPJv+OvGOzwaLKIxXQYZ3nwTAoUwOd87+dYaqUPl515qw1qAygcGZE6wYLu1XxbVmhk3cSW2t/uO/u20XG4CWcl5R3Gu1wk263oY6zymEGc69HBQcGOTD+BSpqd3qMRhNiyLRrvYyP5QApqmN3Hf8LAnnyUCJQHLBNIukhK8U7U92mt6gdEN7pSxczF38gOHBdW4jll4vvFE9EcM7xOd9R3IfxAiQjKCv73CaZAta++bLaGF33VOo/oZQm3zuWi/CUfSzUjrJOIEbHJGs1aKas4+d34+RAv++puu5zAUD+7XbtzrsahQa8G0z8TkwRq35Uvns+M+doMghfDRhx1WUCgijXgRA7fT1hMAjWDtFoKyWCjXm+BhDHT2GLPS5jDLRr9CAgI36LumNQ/M0DfIQYKNwOMVK31lNszLOzQDxK6TfTvJQiwTdR8JW0xo4xshq3eyiHarRJNWDRXDQI6DpfL1QjQatetepCraY+DunTxGFH40L4W8BykrHpcXavJYWl0FycxudFyGXFHYA28evMMmkyMv/B7oyn5BFPvt/3qDmlTn5dg130jDgMBfZVNdhTFMOkXQmZaig8GenWHakpU+iP/tkl0CL1a/IzzEtMg+tA4GeV48HRD9Y/2IqHl+gTNF8cpDRVY9V+9O6RTHdn0WhuddQwb384wK/frOBmltzNg+XFnO4nfUXzAlRY73ctqpXeT0Nk9G0nMm3wDaAKPvlgQclxbhOIP2KbypvCRzUSr9yTq/uKxPONOoybPoPkIXH8aNpxUfrSQ+yCY5xum90K6MZaMmGDz2o38Je/HJsZbvzeMA1NDcBQxqlwDppbZbcG6ehV2D6t7/AdObRca4kXh6lIklmCajhZjcKnGw5Mbb8WCCnbeFLYkTQk8knBMicHnZvrNwSbAuTDz0AiDU4AkRfWfragNkDi9DTmUTTIrzg/10miMkLnoDUCu2RK6u2RDFr2QSH1KznOfBJ7TBYmuGdvLdJerB282h+148aP/YPAx9oS57D+7ZOHAYXv6zkWcaLV8X+2/nGSfe4KKlK2zLgPmYblxA4Dp9xHVoHKsk4UPix7KQjNln1F557AXPTtSLkVSBzf8mquqhmgDC0F41iiRLZZJTtwf4jzvDGFVkq+C1tJlh+NU3fRTdsqPcjG63v/jMCpDtzatgZ+m3UT+75nNIPACRt9kJ3XiDiMk+pI/VS6L6FtAFEuX6GqFt0B2tBVS2pI6blhA==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__.'/VNagWebReader.class.php';
 
$job = new VNagWebReader();
$job->run();
unset($job);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/wordpress_version/WordPressVersionCheck.class.php
0,0 → 1,81
<?php /* <ViaThinkSoftSignature>OJBtqRvIU6hU8LTzanZKhpd9dpHHiBOX4pwyUGXYgEltRcNKKASFsv71lmshrkuxmgCp2q4aa9jB03T0RPOPXtAulRlFpLvsmD7eXHRqt82AC8H2PMw8uoCMk/bqgfAMqf1y0sP9qs5s9faijFgdKlQkJH3nLGDQ3YsN1dYLMwtUQsKtnVobLizdd5tIlyW1OcY5h32Yd2z24CjcgBUbknqBD+I6dBx7TBQWXqX4CwC7N2jDXyn7TBN2CHWtYlY1BldUndt6PXEaaoYOtqcQw/cSc7NvOenQFGQt++Kwur1f31+6HiGbLFGLfrA0sXJWUdYWLHGkNHKmzmPoDZFWweQIadB5QQGtnLWUpPtIsShIg4/G0+Lt6V/janYr0D/IGVnRyXUikh59qNkx942oGF/ozuu39OYyAhyUTbpCT8/PeDwjS2qPbvsZEq2tUDGHHBxq1XW8DmsmLkRCertcVGsG+WLBmxCJLRjI/5UE0zB9XCXwIPOI8+ImtvBgGhEPu63xbORECr6R0L8FWZ8cjCvnrNEFZOSliTQWwUzpcgJTAFSJPlHEF/X4PbqbhsJLU6Z75Q/jIfKWzxzREzkyPKQGDAitKnGwiNZo04tJSxBryd8Vqm0sASmTkSm1TU60C7MOzWCekIekea+lOpoxPwdXuphxwahGTxXkp+FCQ7/K1e/jYOkCgq/Xz7uZRVXK7/bL0QlrwMQtJbbiJHon4pE7aar6yP3mAE6zqXdPzxCRr28ochhY2dFU6RKXK9mMgkAdvalsyksLR4ivEOcGrRW3ZasY8RhLu1UiZKGpVrlanK7E8AqL6moXB5xxTmNeBGBPzWmYJaAFjHp+iFNVy11jGTQD9HW4bQ0vqhj71TyCpmXJnsiF0J3Zurj+iB22U192yBVluuOemOCTfygSySdZXsQCb2dARjnalkyb9ee5j0VrgeI7FYeVne9PkarpWRgvVhEQzLbwcCgRHKpQy0w4V41wx5HdmrcncYntEdbIx0iITKeIFy65VaQYQyk4RNL6PG6jY32gyNqIA7OzwnTYrguBlKhf4Fp9ij8g9xPtXp16Jz1AEzxkbxMzIZeSwQXIv14rbZszTuFJ3LsjH77agS2Gc6nqframOvPF4YszPJUG+EpSLiiuM/5SAXcTB8pDPoaRSVXSg9ouoLjH5BcppDUQqBIaXuJzDvqpfXQzAEBeyZg0jQw/3ylLAIlp4oNmuU+UlmIO4GYlGWVo6eAqH/v/g3cffTVce/OvpjUR0+3bTgmlf8/QC9s/rqtYEJ9jB953TfnSkP1RXP2y0ZlfuumRB2u2mDuJEZrWbZwXdobkfwwLrxPGeucLqPeY+it+yD6tNguvu2c0/BMuPA==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
class WordPressVersionCheck extends VNag {
protected $argSystemDir = null;
 
public function __construct() {
parent::__construct();
 
$this->registerExpectedStandardArguments('Vht');
 
$this->getHelpManager()->setPluginName('check_wordpress_version');
$this->getHelpManager()->setVersion('1.0');
$this->getHelpManager()->setShortDescription('This plugin checks if a local WordPress Webmail system has the latest version installed.');
$this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
$this->getHelpManager()->setSyntax('$SCRIPTNAME$ [-d <directory>]');
$this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
 
// Individual (non-standard) arguments:
$this->addExpectedArgument($this->argSystemDir = new VNagArgument('d', 'directory', VNagArgument::VALUE_REQUIRED, 'wordpressPath', 'The local directory where WordPress installation is located.'));
}
 
protected function get_wordpress_version($path) {
$path = realpath($path) === false ? $path : realpath($path);
 
$cont = @file_get_contents("$path/wp-includes/version.php");
 
if (!preg_match('@\$wp_version = \'(.+)\';@ismU', $cont, $m)) {
throw new Exception("Cannot find version information at $path");
}
 
return $m[1];
}
 
protected function get_latest_version() {
$cont = @file_get_contents('https://wordpress.org/download/');
if (!$cont) {
throw new Exception("Cannot access website with latest version");
}
 
if (!preg_match('@Download WordPress ([0-9\.]+)@ism', $cont, $m)) {
throw new Exception("Cannot find version information on the website");
}
 
return trim($m[1]);
}
 
protected function cbRun($optional_args=array()) {
$system_dir = $this->argSystemDir->getValue();
if (empty($system_dir)) {
throw new Exception("Please specify the directory of the WordPress installation.");
}
$system_dir = realpath($system_dir) === false ? $system_dir : realpath($system_dir);
 
if (!is_dir($system_dir)) {
throw new Exception('Directory "'.$system_dir.'" not found.', false);
}
 
$version = $this->get_wordpress_version($system_dir);
 
$latest_version = $this->get_latest_version();
 
if ($version == $latest_version) {
$this->setStatus(VNag::STATUS_OK);
$this->setHeadline("Version $version at $system_dir", true);
} else {
$this->setStatus(VNag::STATUS_WARNING);
$this->setHeadline("Version $version is outdated (Latest version is $latest_version) at $system_dir", true);
}
}
}
/trunk/plugins/wordpress_version/check_wordpress_version
0,0 → 1,20
#!/usr/bin/php
<?php /* <ViaThinkSoftSignature>Mzlo3XO1AyetqTdWdp4c5CngIzcUyos2y4JIyI4Y5Xt3osdutrFth/1x8muUNkHZ37a7RrR5uM4oTKnzgj+seixYPeRE5CBxN4Ciqe7jHDFMxjRehWL2ly7Oq5WVhrC1QljKGBU9/cHtBaIEtcqkLilBX4MNN4PLuuvHNuI+6qByg66gSGq+Zwt5fAW+4b9HOHxQEPOCQXWx3SR7SwSdnoM73znHWsEqGZHie4UnGajoCUmzuj0ONg2Q8k3g+n+o838Boc2TnWafkjgaHgCf/m0J2wH4z2V4YgtFRZ10DF6UZN3k6Khgc5HOL1IV2le0mcTD70b1JYghEXXgZYn1qhoap9cBDbSgtwjh7zxEiEzy5zP31r0+Ue8H+puuJXhmoBHopOloeD1CWHGWJfoGZ+lKOKTIQJOpVDBLuHIsKb30rBSRgQolcbSpqmlyWgCVK2LTlciYXYb76vDd1yoNaw6slcuJswQQCwRSmn59xgBTy9MMOLRXxv37TMgfzvNAeTZ3HSrAgGkzRyMIM9VrsSM0E6tB9pBS0kB2CEttzX5eqflffYmetM18WtR33YWqVkUF9SxeFHP1Rd5d5siA36KkYoMBkzLm+kb2GvSM4N4gaA1rV8ZYY1cL9OERfT09aqfoXAEtCh88a4HzbyDCCN9zAhl+6PxDDHR1mzUoUyk/Eps6CF78Hp5AfEX17WIxC18CdN2UzvpTMCc+fALRddKxGg1he8U6zf5umkCWFDAAt8oeGcwm4Se0F+veudgfq8wOcT/c3EAFVCV3BuVCZJLBSAiYCJXHY8nbAgWhmfU0M+tu+HKqgzrSIXxFxvpStlTZ4D5eI5oolGdwJiDbP39lLLrRFX5fVJvmzMzi6Tu/1OXW6p2Cx8Cy7/GX6qW2wusEUUjQWPl+F7N4P/X6z8g+/Sql3UgmEZBu1qZzUwXYczhXMPUloSiSK+SzDFf2o5wjXJ/gNks/Wy5AlPvdxa4Qzf5cCITL8jbWzZurVXW+UExZMYoMNDlk8jogjqxr90eoKINJYaM3WDowoS84FZzxWAKrHGUYhKTUAJETC0zwaYI1j94XEktxU/1NBaEdVVbf3zr3DU6xbWHqVnrO1Cs7TOAHTiX1Z9rfo3yIFUnmOAAglfDGJCjghdudp6CMebKRFbQLEfg5J03c+pSan/yqgz1Nc8zBOe1hlAnXZsrzL3b0q/+YGfhHQmh6kP9wZ77IKjfZ4RhvBckUplcB3Cm39j2lgBLVtyUKWopnVVohpakMgw9FuEv0pOGFaDPTibIbgkh5QRBLasrnn5+Hbucke/IfJq8/svSKA2JMfYVjMMudOabsRWYgZmLTx3od3dKyrb8YrBimXUoyl43Meg==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__ . '/WordPressVersionCheck.class.php';
 
$job = new WordPressVersionCheck();
$job->run();
unset($job);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/wordpress_version/icinga2.conf
0,0 → 1,48
// Put this file in /etc/icinga2/conf.d/...
 
// VNag - Nagios Framework for PHP
// Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
// Licensed under the terms of the Apache 2.0 license
//
// Revision 2018-07-15
 
object CheckCommand "vnag_wordpress_version" {
command = [ "/daten/vnag/plugins/wordpress_version/check_wordpress_version" ]
 
arguments = {
"-d" = {
value = "$vnag_wordpress_version_dir$"
description = "Location where the WordPress installation is located"
required = true
}
}
}
 
// Example usage:
//
// apply Service "example_website1_wordpress_version" {
// import "generic-service"
// check_command = "vnag_wordpress_version"
// vars = {
// vnag_wordpress_version_dir = "/var/www/website1/wordpress/"
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_website2_wordpress_version" {
// import "generic-service"
// check_command = "vnag_wordpress_version"
// vars = {
// vnag_wordpress_version_dir = "/var/www/website2/wordpress/"
// }
// assign where host.name == NodeName
// }
//
// apply Service "example_website3_wordpress_version" {
// import "generic-service"
// check_command = "vnag_wordpress_version"
// vars = {
// vnag_wordpress_version_dir = "/var/www/website3/wordpress/"
// }
// assign where host.name == NodeName
// }
/trunk/plugins/x509_expire/X509ExpireCheck.class.php
0,0 → 1,147
<?php /* <ViaThinkSoftSignature>JvUe2EqrSTpzUAa69aGVuvQPVhC4dS9OgSJw+lNJLLFBnB10I8C8EVE5DcrC1/bQ+uF7qNulGCHJktHv8GEUhS79S7VzsuwFo8N1GXxRuanRlk3uCrPtOx8kvgdUesL8dmfCKQAxGHauSogngnj3qyN6PvcKbcBpp+oFzzQvOJrlb3osfKMcaAtJP1k8UYaNvpdT+Osi7jEe6sxRIH4c8iosSumIMHC763S0ngYMFk6i4tzHiyXr3QsfH9afKiVCX+8F/Q9zlj83VHNRsJYFk/z83R74nK8ZEmOWqUtlC3WaHN5ieNwOfwgjCQQP6QBOk/EihVvBuT/RXlZxEpzkzkpevkGfPK0c21XFHFmni6zhMx950oKY3lUXhvjesORZ+wVGN7CVi/ZjjoP0OAqT0dkl9X9t8LA2zIcN8qcq7kfd1T4ySbu88trlmoM4TM8/JE75B7XH/UwsqxX+aG1pqwy9Ea9IkvCRTD1y80bp4HMrrEhStw70j0xPJMB/IxRRQjVoCajN4ABpPpVk5cibj3/KLsWDSSu0PkXqkWBi1i1D+PZvDW/pqPTHLkd4wxj+dLp76kAgaOZ/xKJ6WNXS+bFd95RjURZaOoVYtwSION0tqqtNXTugmnDcrofSAFz+0+ccdLZKXXjlqLHs042ZGZCHW76hjvneraHqpM9svGorm2i3ka88nCG72ssNIaGfEGiVIzneSNiDHzmL5Qb9YLMa2bSH6CEgYmsaVtYmnwxEAPe2fq73/7pAdLXxRznuu5FbVGkjXXF3MjOMEX+EKmIrtaVWvL6ny+EvAI0BYymuuk2H5fvDMzOIGtsAt3whjR2khF/FF1xUls5WgvE7lM6PQftgI11EHNjgjV5EPstThMHuLWbl8GlMCktG/gS8PMJM2arN7VL1NPjDvJ3wath3kEUBZxfP0k1C7FhrL12I3PLy931uPMRtFH7em7zmLe76sYmgludGkR1W5SZCRXwjk2T8q/fOGV3Ra334cr4ix2gw/EjTK1Ojtlidt3qYeKde1N/WK+n2kihOeMjNj28r6l/0ysF5AYL42ZujJnMyyIiOIDEerYNKZKg9+Q5/6fCrTmItuIp0x2SqW29b4fwtMFoPXN6a+XB/f09NTjnZ56tsG3EY7AJHGKZ9MjTvedrJ/cch1wr6LuD6eTaHlf3zFK3Rgzyp/ixZqjVA4zjSrT/xQnoymLp7PjTK8tKcCOFxm2eJ+u3tsdg/UkaXylt+XPr0/QEXhKheAjug2Ylcqf1Aj4LH/WYVrZcUGAFIH/4Bzy7JEI+KRiN9MO3SgSlzEzaQwfXnvm9rMhGawsgbapsRMpAbNDr9qfMO8iSgKy0SBi+16ao0H4bNxPgM6w==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-16
*/
 
declare(ticks=1);
 
class X509ExpireCheck extends VNag {
protected $argFiles = null;
 
public function __construct() {
parent::__construct();
 
$this->registerExpectedStandardArguments('Vhtwcv');
 
$this->getHelpManager()->setPluginName('check_x509_expire');
$this->getHelpManager()->setVersion('1.0');
$this->getHelpManager()->setShortDescription('This plugin checks X.509 (PEM) files and warns if certificates are about to expire.');
$this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
$this->getHelpManager()->setSyntax('$SCRIPTNAME$ [-v] -w <warnSeconds>s -c <critSeconds>s -f "[#]<mask>" [-f "[#]<mask>" [...]]');
$this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
 
// Individual (non-standard) arguments:
$this->addExpectedArgument($this->argFiles = new VNagArgument('f', 'file', VNagArgument::VALUE_REQUIRED, 'mask', 'The files to be checked. This argument can be used multiple times. Wilcards may be used but MUST be passed as string only (not resolved by the Shell). There are two possible checking modes: If you put a # in front of the file mask, only the oldest file of each group will be checked (use this mode e.g. if you have a directory which contains old backups of certificates beside the current working certificate). Otherwise, all files of the file group are checked.'));
 
// In this context, when the user writes "-w 60s" then he actually means "-w @~:60s" or "-w 60s:~", so these commands allow this notation:
$this->warningSingleValueRangeBehaviors[0] = self::SINGLEVALUE_RANGE_VAL_LT_X_BAD;
$this->criticalSingleValueRangeBehaviors[0] = self::SINGLEVALUE_RANGE_VAL_LT_X_BAD;
}
 
private static function humanFriendlyTimeLeft($secs) {
$out = array();
 
if ($expired = $secs < 0) $secs *= -1;
 
$years = floor($secs / 60 / 60 / 24 / 365);
if ($years > 0) $out[] = $years == 1 ? "$years year" : "$years years";
 
$days = floor($secs / 60 / 60 / 24) % 365;
if ($days > 0) $out[] = $days == 1 ? "$days day" : "$days days";
 
$hours = floor($secs / 60 / 60) % 24;
if ($hours > 0) $out[] = $hours == 1 ? "$hours hour" : "$hours hours";
 
$minutes = floor($secs / 60) % 60;
if ($minutes > 0) $out[] = $minutes == 1 ? "$minutes minute" : "$minutes minutes";
 
$seconds = $secs % 60;
if ($seconds > 0) $out[] = $seconds == 1 ? "$seconds second" : "$seconds seconds";
 
return ($expired ? 'EXPIRED SINCE ' : '').implode(", ", $out).($expired ? '' : ' left');
}
 
private static function timeLeft($pemFile) {
$out = array();
 
// TODO: Call PHP's openssl functions instead
exec("openssl x509 -in ".escapeshellarg($pemFile)." -noout -text | grep \"Not After\" | cut -d ':' -f 2-", $out, $code); // TODO: check $code
if ($code != 0) {
throw new VNagException("Error calling openssl!");
}
 
$tim = strtotime($out[0]);
return $tim - time();
}
 
protected function cbRun($optional_args=array()) {
$this->argFiles->require();
 
$countFilesTotal = 0;
$countFilesCrit = 0;
$countFilesWarn = 0;
 
$fileGroupMasks = $this->argFiles->getValue();
if (!is_array($fileGroupMasks)) $fileGroupMasks = array($fileGroupMasks);
foreach ($fileGroupMasks as $fileGroupMask) {
if (substr($fileGroupMask, 0, 1) === '#') {
$fileGroupMask = substr($fileGroupMask, 1); // remove #
 
// Mode 1: Only the youngest file of each group is checked.
// You can use this mode e.g. if you have a folder with downloaded files
// and you want to check if a downloading-script is still downloading
// new files regularly.
 
$files = glob($fileGroupMask);
if (count($files) == 0) continue;
 
$minTimeLeft = null;
foreach ($files as $file) {
$minTimeLeft = is_null($minTimeLeft) ? filemtime($file) : min($minTimeLeft, self::timeLeft($file));
}
 
$countFilesTotal++;
if ($this->checkAgainstCriticalRange($minTimeLeft.'s', false, true)) {
$countFilesCrit++;
$this->addVerboseMessage("File group '$fileGroupMask' oldest file: ".self::humanFriendlyTimeLeft($minTimeLeft)." (Critical)\n", VNag::VERBOSITY_SUMMARY);
} else if ($this->checkAgainstWarningRange($minTimeLeft.'s', false, true)) {
$countFilesWarn++;
$this->addVerboseMessage("File group '$fileGroupMask' oldest file: ".self::humanFriendlyTimeLeft($minTimeLeft)." (Warning)\n", VNag::VERBOSITY_SUMMARY);
} else {
if (($this->getArgumentHandler()->getArgumentObj('w')->available()) || ($this->getArgumentHandler()->getArgumentObj('c')->available())) {
$this->addVerboseMessage("File group '$fileGroupMask' oldest file: ".self::humanFriendlyTimeLeft($minTimeLeft)." (OK)\n", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
} else {
$this->addVerboseMessage("File group '$fileGroupMask' oldest file: ".self::humanFriendlyTimeLeft($minTimeLeft)."\n", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
}
}
} else {
// Mode 2: All files of each group are checked.
 
$files = glob($fileGroupMask);
if (count($files) == 0) continue;
 
foreach ($files as $file) {
$timeLeft = self::timeLeft($file);
$countFilesTotal++;
if ($this->checkAgainstCriticalRange($timeLeft.'s', false, true)) {
$countFilesCrit++;
$this->addVerboseMessage("File $file: ".self::humanFriendlyTimeLeft($timeLeft)." (Critical)\n", VNag::VERBOSITY_SUMMARY);
} else if ($this->checkAgainstWarningRange($timeLeft.'s', false, true)) {
$countFilesWarn++;
$this->addVerboseMessage("File $file: ".self::humanFriendlyTimeLeft($timeLeft)." (Warning)\n", VNag::VERBOSITY_SUMMARY);
} else {
if (($this->getArgumentHandler()->getArgumentObj('w')->available()) || ($this->getArgumentHandler()->getArgumentObj('c')->available())) {
$this->addVerboseMessage("File $file: ".self::humanFriendlyTimeLeft($timeLeft)." (OK)\n", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
} else {
$this->addVerboseMessage("File $file: ".self::humanFriendlyTimeLeft($timeLeft)."\n", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
}
}
}
}
}
 
$msg = array();
$msg[] = "Checked $countFilesTotal certificates";
if ($this->getArgumentHandler()->getArgumentObj('w')->available()) $msg[] = "$countFilesWarn are in warning time range";
if ($this->getArgumentHandler()->getArgumentObj('c')->available()) $msg[] = "$countFilesCrit are in critical time range";
$msg = implode(", ", $msg);
 
$this->setHeadLine($msg);
}
}
/trunk/plugins/x509_expire/check_x509_expire
0,0 → 1,20
#!/usr/bin/php
<?php /* <ViaThinkSoftSignature>jsazuurdTneLpbLNZrodw5PwZqj+lhH51hsHJGkRdHIF9flSOrHKzDZfJqq6AIWWNThkFU9THSZaS61fdK3rNFF2SrBjYQ3cmrH8RxxUOQ2v8dyuaq+o64PbRAKBvr9ZXSE8rJuF1iuMKLw13mm6RUwmpmfmLLr/8gyoChyQYXFSlgCUZK52z0G6Zh/CvJe0vBVPvPrjr8jfx2ebqMa09uL3mERWewP4JjOwZrcJgZe7IDsT5imLxzOQ7ceWDF9dSkKJhGXHyNzjFytJBSP9TPa+/HRjSDxpfAlFgNni2hoNiiQCb5SNg6tL80MWiS+HpjGLskRLdXRTEkU9RejqKEtfXNKLnoVL+xQBpPJf6IKxy7DtWkJN/HoVprL2J9P11JMi9oeVSFimbU7sXl0DqnlUbCcg3skvhDt9tcRfkdK1FRIkUtJysqrDPfjwRusPQ2hYCVo6qWCa4ZXpc9tZlLnGvFgUxUEMzzu1HPQI/pPel4fzqlVSCZNcsZfj/uTpNw84XczyRTJdGyuX0t0GVoJv8yl3RZObwuhtNYpb9nbuGezoJRbuCDOjtfh9cl3kPwnKIGam2tosDMPM96eh5oKnm75nCxWMBZceFZs/8M9/f8hE4Yt0MaqVtZjXtJ58T9fLpDnku5hlYOerDths/ZA+OYX2b6VYp7mh7RLYEiZOBrWjtBDqpOn6xIRz0ytA+FPJiD6U1NHlIBmCMS7TkSaW0l+yckQgO6/qOx4bO+0vUxWR0nAk7kZB8EhaHIOrEnsS8CLBePJBEOmCkr1Pr3yhJEYaRJNca9bBMctl4BmLyu4kAIhgTrijMBvUmRXLf23dVCKOG6Ind08pq4D51SM3HrrzxzJg+W/gMxMDpGah430U0UL9I/nRxrzEIeCsPA96m2pHYSDynqLIlNDc/jXG57l29jhj7bqOKWF4HjkBGITE3mh+ALJPpl8y2yGYxW0bNBQjtg3VZ+DFHjniV2TmCDbtD0KpiDF9E3xfsTcsXeCEBWObEP/uPPNE2jg/rWUAECl1E63Kz3nWqK31vVmzEcIunyUw/eLPi30/WNrJR+wIDA5BCefwBwFt/bnVcMVh3G4dnw+iq5C1KaNGz6XG0dsOfLjxArxt2TqhF04a/zklPCPCp/vHfzU1cCkIk6nMHwmWX5dkyeZxNkoSBx5Fvn4ZkXYyJj8J9Ypy1PZLeZRtfN7jCz4rlcVOBsqLPpBfpARlH0xkwjlbjZwKqjNC5WY+c8t3LwlPDbZY7z/uDUz0XKT1k0JNP+9uw4vTHCC18jdRKygIQSbhx1Vw33c14mXKFZy6X3dhhC7iVhuHCe6908Ds3Z0YcUlyvVxMnGQrHn/jPCWECl9SzsRqZw==</ViaThinkSoftSignature> */ ?>
<?php
 
/*
* VNag - Nagios Framework for PHP
* Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
* Licensed under the terms of the Apache 2.0 license
*
* Revision 2018-07-15
*/
 
declare(ticks=1);
 
require_once __DIR__ . '/../../framework/vnag_framework.inc.php';
require_once __DIR__ . '/X509ExpireCheck.class.php';
 
$job = new X509ExpireCheck();
$job->run();
unset($job);
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/plugins/x509_expire/icinga2.conf
0,0 → 1,46
// Put this file in /etc/icinga2/conf.d/...
 
// VNag - Nagios Framework for PHP
// Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
// Licensed under the terms of the Apache 2.0 license
//
// Revision 2018-07-15
 
object CheckCommand "vnag_x509_expire" {
command = [ "/daten/vnag/plugins/x509_expire/check_x509_expire" ]
 
arguments = {
"-f" = {
value = "$vnag_x509_expire_file$"
description = "File or filemask to be checked. There are two possible checking modes: If you put a # in front of the file mask, only the oldest file of each group will be checked (use this mode e.g. if you have a directory which contains old backups of certificates beside the current working certificate). Otherwise, all files of the file group are checked."
repeat_key = true
required = true
}
"-w" = {
value = "$vnag_x509_expire_warn$"
description = "Max age of file (warning range). You must use a Nagios compatible unit of measure (i.e. seconds)."
}
"-c" = {
value = "$vnag_x509_expire_crit$"
description = "Max age of file (critical range). You must use a Nagios compatible unit of measure (i.e. seconds)."
}
"-v" = {
set_if = "$vnag_x509_expire_verbose$"
description = "Additionally list files which are OK, not just the files which are out of the time range."
}
}
}
 
// Example usage:
//
// apply Service "example_letsencrypt_expiration" {
// import "generic-service"
// check_command = "vnag_x509_expire"
// vars = {
// vnag_x509_expire_file = [ "/daten/ssl/letsencrypt/*/certificate.pem" ]
// vnag_x509_expire_warn = "86400s" // 24h
// vnag_x509_expire_crit = "144000s" // 40h
// vnag_x509_expire_verbose = false
// }
// assign where host.name == NodeName
// }
/trunk/sign_all
0,0 → 1,4
#!/bin/bash
DIR=$( dirname "$0" )
"$DIR"/signtool/sign framework/* plugins/*/*
 
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/signtool/public.pem
0,0 → 1,25
-----BEGIN PUBLIC KEY-----
MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEA4UEmad2KHWzfGLcAzbOD
IhqWyoPA1Cg4zN5YK/CWUiE7sh2CNinIwYqGnIOhZLp54/Iyv3H05QeWJU7kD+jQ
5JwR8+pqk8ZGBfqlxXUBJ2bZhYIBJZYfilSROa7jgPPrrw0CjdGLmM3wmc8ztQRv
4GpP7MaKVyVOsRz5xEcpzghWZ+Cl8Nxq1Vo02RkMYOOPA16abxZ65lVM8Vv2EKGf
/VAVViTFvLWPxggvt1fbJJniC0cwt8gjzFXt6IJJSRlqc1lOO9ZIa/EWDKuHKQ1n
ENQCqnuVPFDZU3lU20Z+6+EA0YngcvNYi3ucdIvgBd4Yv5FetzuxiOZUoDRfh/3R
6dCJ8CvRiq0BSZcynTIWNmF3AVsH7vjxZe8kMDbwZNnR0suZ5MfBh6L/s1lCEWlS
GwmCLc3MnOLxq3JLnfmbVa509YxlUamdSswnvzes28AjnzQ3LQchspP2a8bSXH6/
qpbwvmV5WiNgwJck04VhaXrRRy3XFSwuk7KU/L4aqadXP26kgDqIYNvPXSa9JyGc
14zwdmAtn36o8vpXM/A7GhdWqgPLlJbdTdK6IfwpBs8P/JB6y3t6RzAGiEOITdj9
QUhW+sAoKno0j4WT7s80vWNWz37WoFJcvVLnVEYitnW6DqM+GOt2od3g6WgI6dOa
MESA4J44Y4x1gXBw/M6F/ZngP4EJoAUG0GbzsaZ6HKLt4pDTZmw8PnNcXrOMYkr/
N5EliTXil45DCaLkgNJmpdXjNpIvShW4ogq2osw+SQUalnAbW8ddiaOVCdgXkDFq
gvnl5QSeUrKPF5v+vlnwWar6Rp7iInQpnA+PTSbAlO3Dd9WqbWx+uNoI/kXUlN0O
a/vi5Uwat2Bz3N+jIpnBqg4+O+SG0z3UCVmT6Leg+kqO/rXbzoVv/DV7E30vTqdo
wsswdJEM1BI7Wyid6HPwBek+rdv77gUg3W37vUcdfKxsYRcoHriXLHpmENznJcEx
/nvilw6To1zx2LKmM/p56MQriKkXnqoOBpkpn3PaWyXZKY9xJNTAbcSP3haE7z9p
PzJw88KI8dnYuFg4yS/AgmVGAUtu3bhDG4qF9URu2ck868zViH996lraYkmFIWJG
r7h1LImhrwDEJvb/rOW8QvOZBX9H6pcSKs/LQbeoy6HMIOTlny+S15xtiS4t6Ayv
3m0ry5c0qkl/mgKvGpeRnNlrcr6mb2fzxxGvcuBzi25wgIbRLPgJoqsmeBvW1OLU
+9DpkNvitEJnPRo86v0VF86aou12Sm8Wb4mtrQ7h3qLIYvw2LN2mYh4WlgrSwPpx
YvE2+vWapilnnDWoiu2ZmDWa7WW/ihqvX9fmp/qzxQvJmBYIN8dFpgcNLqSx526N
bwIDAQAB
-----END PUBLIC KEY-----
/trunk/signtool/sign
0,0 → 1,58
#!/usr/bin/php
<?php
 
// Generate keypair with:
// openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:8192
// openssl rsa -pubout -in private.pem -out public.pem
 
if ($argc < 2) {
die("Syntax: $argv[0] file1 [file2 ...]\n");
}
 
if (!file_exists(__DIR__.'/private.pem')) {
echo "Key private.pem not found\n";
}
 
for ($i=1; $i<$argc; $i++) {
$file = $argv[$i];
 
$cont = file_get_contents($file);
$original = $cont;
 
if (strpos($cont, '<?php') === false) {
echo "Not a PHP file: $file\n";
continue;
}
 
$naked = preg_replace('@<\?php /\* <ViaThinkSoftSignature>(.+)</ViaThinkSoftSignature> \*/ \?>\n@ismU', '', $cont);
 
$hash = hash("sha256", $naked.basename($file));
 
$pkeyid = @openssl_pkey_get_private('file://'.__DIR__.'/private.pem');
openssl_sign($hash, $signature, $pkeyid, OPENSSL_ALGO_SHA256);
openssl_free_key($pkeyid);
 
if (!$signature) {
echo "ERROR: $file\n";
continue;
}
 
$sign_line = '<?php /* <ViaThinkSoftSignature>'.base64_encode($signature).'</ViaThinkSoftSignature> */ ?>';
if (substr($cont,0,2) === '#!') {
// Preserve shebang
$shebang_pos = strpos($naked, "\n");
$shebang = substr($naked, 0, $shebang_pos);
$rest = substr($naked, $shebang_pos+1);
$cont = $shebang."\n".$sign_line."\n".$rest;
} else {
$cont = $sign_line."\n".$naked;
}
 
if ($cont != $original) {
echo "Signed: $file\n";
file_put_contents($file, $cont);
} else {
echo "Already signed: $file\n";
}
}
 
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/signtool/verify
0,0 → 1,21
#!/usr/bin/php
<?php
 
$file = $argv[1];
 
$cont = file_get_contents($file);
 
if (!preg_match('@<\?php /\* <ViaThinkSoftSignature>(.+)</ViaThinkSoftSignature> \*/ \?>\n@ismU', $cont, $m)) {
die("File $file not signed\n");
}
$signature = base64_decode($m[1]);
 
$naked = preg_replace('@<\?php /\* <ViaThinkSoftSignature>(.+)</ViaThinkSoftSignature> \*/ \?>\n@ismU', '', $cont);
$hash = hash("sha256", $naked.basename($file));
 
$public_key = file_get_contents(__DIR__.'/public.pem');
if (!openssl_verify($hash, $signature, $public_key, OPENSSL_ALGO_SHA256)) {
die("Signature invalid\n");
}
 
echo "Signature valid\n";
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/signtool
Property changes:
Added: svn:ignore
+private.pem
/trunk/stable.tar.gz
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/.
Property changes:
Added: svn:ignore
+_mock
+plugins_intern