diff options
author | Micah <micah@leap.se> | 2016-07-12 16:46:11 -0400 |
---|---|---|
committer | Micah <micah@leap.se> | 2016-07-12 16:46:11 -0400 |
commit | 26aac7ccf240b06d65616bdd00ae472d980aaea9 (patch) | |
tree | fc9b582d71c32a470bc677d80c2d6c9abe6970d3 | |
parent | f5775156d8d8800247b8917ab6212c7eed16a124 (diff) |
git subrepo clone https://leap.se/git/puppet_nagios puppet/modules/nagios
subrepo:
subdir: "puppet/modules/nagios"
merged: "e6fee3c"
upstream:
origin: "https://leap.se/git/puppet_nagios"
branch: "master"
commit: "e6fee3c"
git-subrepo:
version: "0.3.0"
origin: "https://github.com/ingydotnet/git-subrepo"
commit: "1e79595"
Change-Id: Ib7105f359ea2c3ae6490bff4fcecbede2511eaf0
117 files changed, 11911 insertions, 0 deletions
diff --git a/puppet/modules/nagios/.gitrepo b/puppet/modules/nagios/.gitrepo new file mode 100644 index 00000000..b832fa2a --- /dev/null +++ b/puppet/modules/nagios/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://leap.se/git/puppet_nagios + branch = master + commit = e6fee3c731f68ccf8b6add8ada2162c7ad2b8407 + parent = f5775156d8d8800247b8917ab6212c7eed16a124 + cmdver = 0.3.0 diff --git a/puppet/modules/nagios/LICENSE b/puppet/modules/nagios/LICENSE new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/puppet/modules/nagios/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/puppet/modules/nagios/README b/puppet/modules/nagios/README new file mode 100644 index 00000000..0c42b4a7 --- /dev/null +++ b/puppet/modules/nagios/README @@ -0,0 +1,305 @@ +Introduction/Notes +================== + +This modules was inspired and based on the work of David Schmitt +The immerda project group adapted and improved this module. +Mainly we made it using the new native puppet nagios commands +as well we made it more modular to fit for multidistro usage. + +In it's current form, this module can be used on CentOS and Debian. + + +Overview +======== + +To use the nagios resources in an puppetmaster setup you need to activate +[storeconfigs](https://docs.puppetlabs.com/puppet/latest/reference/configuration.html#storeconfigs) on the puppetmaster. +You can also use this module in a masterless setup, please set the +`storeconfigs` parameter to `false` when declaring the nafios class. + +You need to be running version 0.25 or later of puppet. + + +Monitor +------- + +On one node the "nagios" class has to be included. By default this installs +apache using the "apache" module. To use lighttpd instead, set the "httpd" +parameter to the "nagios" class to "lighttpd", or, if the web server is not to +be managed by puppet, set the "httpd" parameter to "absent". + + +Hosts +----- + +On a node which shall be monitored with nagios, include the "nagios::target". +This just creates a host declaration for this host's "$::ipaddress" fact. If +the $::ipaddress of your target is not the one you wish to modify, you can use +"nagios::target::fqdn" instead, which will use the $::fqdn fact of the host instead. + +Pass the $parents variable to the target class for enabling the reachability +features of nagios. If a node needs more customisation, use the +native "@@nagios_host" type directly (the double-ampersand declares the object +as an exported resource). + +To monitor hosts not managed by puppet, add "nagios_host" objects to the +monitoring node. The required parameters are "alias", "address" and "use". If +you don't specify a proper nagios template with the "use" parameter, some extra +parameters are needed. You may look up the nagios documentation for this. + + +Services +-------- + +Services can be monitored by using the "nagios::service" component. + +The simplest form is: + + nagios::service { 'check_http': + check_command => 'http_port!80', + } + +The intention being obviously to put such declarations into a component defining +a service, thereby being automatically applied together with all instances of +the service. + +Obviously, the check command must either be defined using nagios_command objects +(some are supplied in nagios::defaults::commands) or in the nagios configuration +files directly. + +NRPE client configuration +========================= + +To setup a machine as an NRPE client, the class 'nagios::nrpe' should be used: + + class { 'nagios::nrpe': + allowed_hosts => '10.2.3.4,10.5.6.7', + } + +The class can take the following parameters to change configuration or +configuration directory: + + * $cfg_dir : Defines the path to the NRPE configuration. The default is to use + the path used by packages per your distro. + + * $pid_file : Sets the path of the PID file. The default value is the path + used by init script shipped with your distro's packages. + + * $plugin_dir : Defines the path in which nagios plugins that are to be + executed with NRPE commands are stored. The default value is the path where + your distro's nagios package stores plugins. + + * $server_address : The IP address to which the NRPE client daemon should + bind. The default behaviour is to bind to all IPs. + + * $allowed_hosts : A string containing a comma-separated list of host IPs that + are allowed to request NRPE commands to be run. The default value is to + allow only 127.0.0.1, so you might want to pass in a list of additional host + IPs. + + * $dont_blame : A string that enables ('1') or disables ('0') NRPE command + arguments. Enabling arguments can lead to potentials of shell escapes so it + should be used with caution and only if absolutely needed. This is disabled + by default. + +NRPE Services +------------- + +Some Nagios services need to be checked via NRPE. The following will make the +nagios server define a service that will check the NRPE command 'check_cpu' on +the current node: + + nagios::service { 'CPU Usage': + use_nrpe => true, + check_command => "check_cpu", + nrpe_args => "-t 60" + } + +NRPE Commands +------------- + +To be able to call NRPE commands on a host, one needs to define that command +and what it is going to execute: + + nagios::nrpe::command { 'debsums': + check_command => '/usr/lib/nagios/plugins/check_debsums openssh-server' + } + + +Upgrade Notes +============= + +The nagios::target bits have been reworked, the notable changes that +may affect an upgrade are: + +. previous versions had nagios::target::nat which used the $::fqdn for +the address part of nagios::target, this has been renamed to +nagios::target::fqdn to be more clear. if you were using +nagios::target::nat then you will need to change those references to +::fqdn + +. previous versions of this module used $::fqdn for the nagios::target +address, now it is using $::ipaddress. If you need $::fqdn, use +nagios::target::fqdn instead of nagios::target + +. previous versions of nagios_host used the parameter named 'ip', that +has been changed to 'address' + + +IRC bot +======= + +Notifications can easily be sent to an IRC channel by using a bot. To do so, +simply include 'nagios::irc_bot' on the nagios server and define the right +$nagios_nsa_* variables (see the 'Variables' section below). + +You can then use the notification commands 'notify-by-irc' and +'host-notify-by-irc' with service and host definitions to make them report +state changes over IRC. + +Caveats +======= + + +Consistency/Validation/Verification +----------------------------------- + +After convergance of the configuration, the system is obviously consistent. +That is, all defined services are monitored. The problem is though, that it is +neither automatically valid - it is not guaranteed that all components declare a +nagios::service - and even if the configuration is valid it definitly is +unverified, since that is always a judgment call for an external observer. + + +Removal of nagios objects +------------------------- + +This module does not automatically purge nagios objects such as hosts and +services that become absent from the manifests. One must set ensure => absent +to guarantee the removal of nagios objects from the configuration as desired. + + +Templates not supported using native types +------------------------------------------ + +Templates of hosts and services cannot yet be defined using native types. In +this module, they are provided using a file resource by the class +nagios::defaults::templates + +See : http://projects.reductivelabs.com/issues/1180 + + +Variables +========= + +Options to change the behavior of the nagios class: + +- allow_external_cmd: Set to true, if you'd like to ensure that your http + daemon can write to the external command file. You + may also need to flip "check_external_commands" in + "nagios.cfg" to enable this functionality. + +For the irc_bot class: + +- nsa_socket: This optional variable can be used to specify the path to + the socket file that the IRC daemon should use. + +- nsa_server: When using the IRC bot, this defines the server address of + the IRC network on which the bot will connect. + +- nsa_port: Defines the port number on the IRC server on which the bot + should connect. When this variable is not set, the port used + by default is 6667. + +- nsa_nickname: This is the nickname that the IRC bot will take. + +- nsa_password: Some networks require a password to connect to them. + This defines such a password. + +- nsa_channel: The name of the channel that the IRC bot will join and + will post notifications to. + +- nsa_pidfile: This optional variable can be used to define the path to + the file that will contain the process ID of the IRC bot + daemon. +- nsa_realname: The IRC bot user's real name that will be displayed. By + default, the real name is 'Nagios'. + +- nsa_usenotices: The IRC bot will by default "say" to the channel the + nagios message, but you can switch this variable to + 'notice' if you would prefer them to be sent as IRC + NOTICE messages. + +PNP4Nagios integration +====================== + +For PNP4Nagios integration information, please see README.pnp4nagios + +Examples +======== + +Usage example: + +~~~ +node nagios { + + class { 'nagios': } -> class { 'nagios::defaults': } + + # Declare another nagios command + nagios::command { http_port: + command_line => '/usr/lib/nagios/plugins/check_http -p $ARG1$ -H $HOSTADDRESS$ -I $HOSTADDRESS$' + } + + # Declare unmanaged hosts + nagios_host { + 'router01.mydomain.com': + alias => 'router01', + notes => 'MyDomain Gateway', + address => '10.0.0.1', + use => 'generic-host'; + 'router02.mydomain.com': + alias => 'router02', + address => '192.168.0.1', + parents => 'router01', + use => 'generic-host'; + } + +} + + +node target { + + # Monitor this host + class{'nagios::target': + parents = 'router01' + } + + # monitor a service + $apache2_port = 8080 + include apache2 + + # This actually does this somewhere: + #nagios::service { "http_${apache2_port}": + # check_command => "http_port!${apache2_port}" + #} + +} +~~~ + +TODO +==== + +- Provide a default http vhost +- Add facility to deploy nagios plugins +- Add more useful commands and services +- When Puppet will support them, supply nagios templates using native types + + +License +======= + +Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at> +See the file LICENSE in the top directory for the full license. + +Copyright (C) 2010 Riseup Networks <micah@riseup.net> + diff --git a/puppet/modules/nagios/README.pnp4nagios b/puppet/modules/nagios/README.pnp4nagios new file mode 100644 index 00000000..dd407021 --- /dev/null +++ b/puppet/modules/nagios/README.pnp4nagios @@ -0,0 +1,65 @@ +PNP4Nagios integration +====================== + +As of 2012/01 debian packages for pnp4nagios are availible from lenny-backports on. + +See http://docs.pnp4nagios.org/pnp-0.6/start for installation notes. + +Integration in the nagios/icinga webinterface is configured by including either +the nagios::pnp4nagios or the nagios::pnp4nagios::popup class, the later one +includes fancy popups when you hoover over the extra service action image. For +hosts you need to use the host-pnp definition, for services the srv-pnp def. +i.e. + + @@nagios_service { "ping_example_node": + use => "generic-service,srv-pnp", + ... + + nagios_host { 'example_node': + use => 'generic-host,host-pnp', + ... + +In the default config files the "Bulk Mode with NPCD" is used +(see http://docs.pnp4nagios.org/en/pnp-0.6/config for more infos about the different +modes). + +Include the nagios::pnp4nagios::popup class for fancy popups when you hoover over +the extra service action image. + + +Please include this in your nagios.cfg: + +process_performance_data=1 + +#http://docs.pnp4nagios.org/en/pnp-0.6/config#bulk_mode_mit_npcd +# +# Service Performance-Data +# +service_perfdata_file=/var/lib/nagios3/service-perfdata +service_perfdata_file_template=DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$ +service_perfdata_file_mode=a +service_perfdata_file_processing_interval=15 +service_perfdata_file_processing_command=process-service-perfdata-file-pnp4nagios-bulk-npcd + +# +# Host Performance-Data +# +host_perfdata_file=/var/lib/nagios3/host-perfdata +host_perfdata_file_template=DATATYPE::HOSTPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tHOSTPERFDATA::$HOSTPERFDATA$\tHOSTCHECKCOMMAND::$HOSTCHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$ +host_perfdata_file_mode=a +host_perfdata_file_processing_interval=15 +host_perfdata_file_processing_command=process-host-perfdata-file-pnp4nagios-bulk-npcd + + +For hosts you need to use the host-pnp definition, for services the srv-pnp def. +i.e. + + @@nagios_service { "ping_example_node": + use => "generic-service,srv-pnp", + ... + + nagios_host { 'example_node': + use => 'generic-host,host-pnp', + ... + + diff --git a/puppet/modules/nagios/files/configs/CentOS/cgi.cfg b/puppet/modules/nagios/files/configs/CentOS/cgi.cfg new file mode 100644 index 00000000..cd625d4c --- /dev/null +++ b/puppet/modules/nagios/files/configs/CentOS/cgi.cfg @@ -0,0 +1,280 @@ +################################################################# +# +# CGI.CFG - Sample CGI Configuration File for Nagios 2.9 +# +# Last Modified: 11-21-2006 +# +################################################################# + + +# MAIN CONFIGURATION FILE +# This tells the CGIs where to find your main configuration file. +# The CGIs will read the main and host config files for any other +# data they might need. + +main_config_file=/etc/nagios/nagios.cfg + + + +# PHYSICAL HTML PATH +# This is the path where the HTML files for Nagios reside. This +# value is used to locate the logo images needed by the statusmap +# and statuswrl CGIs. + +physical_html_path=/usr/share/nagios/share + + + +# URL HTML PATH +# This is the path portion of the URL that corresponds to the +# physical location of the Nagios HTML files (as defined above). +# This value is used by the CGIs to locate the online documentation +# and graphics. If you access the Nagios pages with an URL like +# http://www.myhost.com/nagios, this value should be '/nagios' +# (without the quotes). + +url_html_path=/nagios + + + +# CONTEXT-SENSITIVE HELP +# This option determines whether or not a context-sensitive +# help icon will be displayed for most of the CGIs. +# Values: 0 = disables context-sensitive help +# 1 = enables context-sensitive help + +show_context_help=0 + + + +# NAGIOS PROCESS CHECK COMMAND +# This is the full path and filename of the program used to check +# the status of the Nagios process. It is used only by the CGIs +# and is completely optional. However, if you don't use it, you'll +# see warning messages in the CGIs about the Nagios process +# not running and you won't be able to execute any commands from +# the web interface. The program should follow the same rules +# as plugins; the return codes are the same as for the plugins, +# it should have timeout protection, it should output something +# to STDIO, etc. +# +# Note: The command line for the check_nagios plugin below may +# have to be tweaked a bit, as different versions of the plugin +# use different command line arguments/syntaxes. + +#nagios_check_command=/usr/lib64/nagios/plugins/check_nagios /var/log/nagios/status.dat 5 '/usr/sbin/nagios' + + + +# AUTHENTICATION USAGE +# This option controls whether or not the CGIs will use any +# authentication when displaying host and service information, as +# well as committing commands to Nagios for processing. +# +# Read the HTML documentation to learn how the authorization works! +# +# NOTE: It is a really *bad* idea to disable authorization, unless +# you plan on removing the command CGI (cmd.cgi)! Failure to do +# so will leave you wide open to kiddies messing with Nagios and +# possibly hitting you with a denial of service attack by filling up +# your drive by continuously writing to your command file! +# +# Setting this value to 0 will cause the CGIs to *not* use +# authentication (bad idea), while any other value will make them +# use the authentication functions (the default). + +use_authentication=1 + + + +# DEFAULT USER +# Setting this variable will define a default user name that can +# access pages without authentication. This allows people within a +# secure domain (i.e., behind a firewall) to see the current status +# without authenticating. You may want to use this to avoid basic +# authentication if you are not using a secure server since basic +# authentication transmits passwords in the clear. +# +# Important: Do not define a default username unless you are +# running a secure web server and are sure that everyone who has +# access to the CGIs has been authenticated in some manner! If you +# define this variable, anyone who has not authenticated to the web +# server will inherit all rights you assign to this user! + +#default_user_name=guest + + + +# SYSTEM/PROCESS INFORMATION ACCESS +# This option is a comma-delimited list of all usernames that +# have access to viewing the Nagios process information as +# provided by the Extended Information CGI (extinfo.cgi). By +# default, *no one* has access to this unless you choose to +# not use authorization. You may use an asterisk (*) to +# authorize any user who has authenticated to the web server. + +#authorized_for_system_information=nagiosadmin,theboss,jdoe +authorized_for_system_information=admin + +# CONFIGURATION INFORMATION ACCESS +# This option is a comma-delimited list of all usernames that +# can view ALL configuration information (hosts, commands, etc). +# By default, users can only view configuration information +# for the hosts and services they are contacts for. You may use +# an asterisk (*) to authorize any user who has authenticated +# to the web server. + +#authorized_for_configuration_information=nagiosadmin,jdoe +authorized_for_configuration_information=admin + + + +# SYSTEM/PROCESS COMMAND ACCESS +# This option is a comma-delimited list of all usernames that +# can issue shutdown and restart commands to Nagios via the +# command CGI (cmd.cgi). Users in this list can also change +# the program mode to active or standby. By default, *no one* +# has access to this unless you choose to not use authorization. +# You may use an asterisk (*) to authorize any user who has +# authenticated to the web server. + +#authorized_for_system_commands=nagiosadmin +authorized_for_system_commands=admin + + + +# GLOBAL HOST/SERVICE VIEW ACCESS +# These two options are comma-delimited lists of all usernames that +# can view information for all hosts and services that are being +# monitored. By default, users can only view information +# for hosts or services that they are contacts for (unless you +# you choose to not use authorization). You may use an asterisk (*) +# to authorize any user who has authenticated to the web server. + + +#authorized_for_all_services=nagiosadmin,guest +authorized_for_all_services=admin +#authorized_for_all_hosts=nagiosadmin,guest +authorized_for_all_hosts=admin + + + +# GLOBAL HOST/SERVICE COMMAND ACCESS +# These two options are comma-delimited lists of all usernames that +# can issue host or service related commands via the command +# CGI (cmd.cgi) for all hosts and services that are being monitored. +# By default, users can only issue commands for hosts or services +# that they are contacts for (unless you you choose to not use +# authorization). You may use an asterisk (*) to authorize any +# user who has authenticated to the web server. + +#authorized_for_all_service_commands=nagiosadmin +authorized_for_all_service_commands=admin +#authorized_for_all_host_commands=nagiosadmin +authorized_for_all_host_commands=admin + + + + +# STATUSMAP BACKGROUND IMAGE +# This option allows you to specify an image to be used as a +# background in the statusmap CGI. It is assumed that the image +# resides in the HTML images path (i.e. /usr/local/nagios/share/images). +# This path is automatically determined by appending "/images" +# to the path specified by the 'physical_html_path' directive. +# Note: The image file may be in GIF, PNG, JPEG, or GD2 format. +# However, I recommend that you convert your image to GD2 format +# (uncompressed), as this will cause less CPU load when the CGI +# generates the image. + +#statusmap_background_image=smbackground.gd2 + + + +# DEFAULT STATUSMAP LAYOUT METHOD +# This option allows you to specify the default layout method +# the statusmap CGI should use for drawing hosts. If you do +# not use this option, the default is to use user-defined +# coordinates. Valid options are as follows: +# 0 = User-defined coordinates +# 1 = Depth layers +# 2 = Collapsed tree +# 3 = Balanced tree +# 4 = Circular +# 5 = Circular (Marked Up) + +default_statusmap_layout=5 + + + +# DEFAULT STATUSWRL LAYOUT METHOD +# This option allows you to specify the default layout method +# the statuswrl (VRML) CGI should use for drawing hosts. If you +# do not use this option, the default is to use user-defined +# coordinates. Valid options are as follows: +# 0 = User-defined coordinates +# 2 = Collapsed tree +# 3 = Balanced tree +# 4 = Circular + +default_statuswrl_layout=4 + + + +# STATUSWRL INCLUDE +# This option allows you to include your own objects in the +# generated VRML world. It is assumed that the file +# resides in the HTML path (i.e. /usr/local/nagios/share). + +#statuswrl_include=myworld.wrl + + + +# PING SYNTAX +# This option determines what syntax should be used when +# attempting to ping a host from the WAP interface (using +# the statuswml CGI. You must include the full path to +# the ping binary, along with all required options. The +# $HOSTADDRESS$ macro is substituted with the address of +# the host before the command is executed. +# Please note that the syntax for the ping binary is +# notorious for being different on virtually ever *NIX +# OS and distribution, so you may have to tweak this to +# work on your system. + +ping_syntax=/bin/ping -n -U -c 5 $HOSTADDRESS$ + + + +# REFRESH RATE +# This option allows you to specify the refresh rate in seconds +# of various CGIs (status, statusmap, extinfo, and outages). + +refresh_rate=90 + + + +# SOUND OPTIONS +# These options allow you to specify an optional audio file +# that should be played in your browser window when there are +# problems on the network. The audio files are used only in +# the status CGI. Only the sound for the most critical problem +# will be played. Order of importance (higher to lower) is as +# follows: unreachable hosts, down hosts, critical services, +# warning services, and unknown services. If there are no +# visible problems, the sound file optionally specified by +# 'normal_sound' variable will be played. +# +# +# <varname>=<sound_file> +# +# Note: All audio files must be placed in the /media subdirectory +# under the HTML path (i.e. /usr/local/nagios/share/media/). + +#host_unreachable_sound=hostdown.wav +#host_down_sound=hostdown.wav +#service_critical_sound=critical.wav +#service_warning_sound=warning.wav +#service_unknown_sound=warning.wav +#normal_sound=noproblem.wav + diff --git a/puppet/modules/nagios/files/configs/CentOS/nagios.cfg b/puppet/modules/nagios/files/configs/CentOS/nagios.cfg new file mode 100644 index 00000000..b88e3db7 --- /dev/null +++ b/puppet/modules/nagios/files/configs/CentOS/nagios.cfg @@ -0,0 +1,949 @@ +############################################################################## +# +# NAGIOS.CFG - Sample Main Config File for Nagios 2.10 +# +# Read the documentation for more information on this configuration +# file. I've provided some comments here, but things may not be so +# clear without further explanation. +# +# Last Modified: 12-21-2006 +# +############################################################################## + + +# LOG FILE +# This is the main log file where service and host events are logged +# for historical purposes. This should be the first option specified +# in the config file!!! + +log_file=/var/log/nagios/nagios.log + + + +# OBJECT CONFIGURATION FILE(S) +# This is the configuration file in which you define hosts, host +# groups, contacts, contact groups, services, etc. I guess it would +# be better called an object definition file, but for historical +# reasons it isn't. You can split object definitions into several +# different config files by using multiple cfg_file statements here. +# Nagios will read and process all the config files you define. +# This can be very useful if you want to keep command definitions +# separate from host and contact definitions... + +# Puppet-managed configuration files +cfg_file=/etc/nagios/nagios_templates.cfg +cfg_file=/etc/nagios/nagios_command.cfg +cfg_file=/etc/nagios/nagios_contact.cfg +cfg_file=/etc/nagios/nagios_contactgroup.cfg +cfg_file=/etc/nagios/nagios_host.cfg +cfg_file=/etc/nagios/nagios_hostdependency.cfg +cfg_file=/etc/nagios/nagios_hostescalation.cfg +cfg_file=/etc/nagios/nagios_hostextinfo.cfg +cfg_file=/etc/nagios/nagios_hostgroup.cfg +cfg_file=/etc/nagios/nagios_hostgroupescalation.cfg +cfg_file=/etc/nagios/nagios_service.cfg +cfg_file=/etc/nagios/nagios_servicedependency.cfg +cfg_file=/etc/nagios/nagios_serviceescalation.cfg +cfg_file=/etc/nagios/nagios_serviceextinfo.cfg +cfg_file=/etc/nagios/nagios_servicegroup.cfg +cfg_file=/etc/nagios/nagios_timeperiod.cfg + +# OBJECT CACHE FILE +# This option determines where object definitions are cached when +# Nagios starts/restarts. The CGIs read object definitions from +# this cache file (rather than looking at the object config files +# directly) in order to prevent inconsistencies that can occur +# when the config files are modified after Nagios starts. + +object_cache_file=/var/log/nagios/objects.cache + + + +# RESOURCE FILE +# This is an optional resource file that contains $USERx$ macro +# definitions. Multiple resource files can be specified by using +# multiple resource_file definitions. The CGIs will not attempt to +# read the contents of resource files, so information that is +# considered to be sensitive (usernames, passwords, etc) can be +# defined as macros in this file and restrictive permissions (600) +# can be placed on this file. + +resource_file=/etc/nagios/private/resource.cfg + + + +# STATUS FILE +# This is where the current status of all monitored services and +# hosts is stored. Its contents are read and processed by the CGIs. +# The contents of the status file are deleted every time Nagios +# restarts. + +status_file=/var/log/nagios/status.dat + + + +# NAGIOS USER +# This determines the effective user that Nagios should run as. +# You can either supply a username or a UID. + +nagios_user=nagios + + + +# NAGIOS GROUP +# This determines the effective group that Nagios should run as. +# You can either supply a group name or a GID. + +nagios_group=nagios + + + +# EXTERNAL COMMAND OPTION +# This option allows you to specify whether or not Nagios should check +# for external commands (in the command file defined below). By default +# Nagios will *not* check for external commands, just to be on the +# cautious side. If you want to be able to use the CGI command interface +# you will have to enable this. Setting this value to 0 disables command +# checking (the default), other values enable it. + +check_external_commands=0 + + + +# EXTERNAL COMMAND CHECK INTERVAL +# This is the interval at which Nagios should check for external commands. +# This value works of the interval_length you specify later. If you leave +# that at its default value of 60 (seconds), a value of 1 here will cause +# Nagios to check for external commands every minute. If you specify a +# number followed by an "s" (i.e. 15s), this will be interpreted to mean +# actual seconds rather than a multiple of the interval_length variable. +# Note: In addition to reading the external command file at regularly +# scheduled intervals, Nagios will also check for external commands after +# event handlers are executed. +# NOTE: Setting this value to -1 causes Nagios to check the external +# command file as often as possible. + +#command_check_interval=15s +command_check_interval=-1 + + + +# EXTERNAL COMMAND FILE +# This is the file that Nagios checks for external command requests. +# It is also where the command CGI will write commands that are submitted +# by users, so it must be writeable by the user that the web server +# is running as (usually 'nobody'). Permissions should be set at the +# directory level instead of on the file, as the file is deleted every +# time its contents are processed. + +command_file=/var/spool/nagios/cmd/nagios.cmd + + + +# EXTERNAL COMMAND BUFFER SLOTS +# This settings is used to tweak the number of items or "slots" that +# the Nagios daemon should allocate to the buffer that holds incoming +# external commands before they are processed. As external commands +# are processed by the daemon, they are removed from the buffer. + +external_command_buffer_slots=4096 + + + +# COMMENT FILE +# This is the file that Nagios will use for storing host and service +# comments. + +comment_file=/var/log/nagios/comments.dat + + + +# DOWNTIME FILE +# This is the file that Nagios will use for storing host and service +# downtime data. + +downtime_file=/var/log/nagios/downtime.dat + + + +# LOCK FILE +# This is the lockfile that Nagios will use to store its PID number +# in when it is running in daemon mode. + +lock_file=/var/run/nagios.pid + + + +# TEMP FILE +# This is a temporary file that is used as scratch space when Nagios +# updates the status log, cleans the comment file, etc. This file +# is created, used, and deleted throughout the time that Nagios is +# running. + +temp_file=/var/log/nagios/nagios.tmp + + + +# EVENT BROKER OPTIONS +# Controls what (if any) data gets sent to the event broker. +# Values: 0 = Broker nothing +# -1 = Broker everything +# <other> = See documentation + +event_broker_options=-1 + + + +# EVENT BROKER MODULE(S) +# This directive is used to specify an event broker module that should +# by loaded by Nagios at startup. Use multiple directives if you want +# to load more than one module. Arguments that should be passed to +# the module at startup are seperated from the module path by a space. +# +# Example: +# +# broker_module=<modulepath> [moduleargs] + +#broker_module=/somewhere/module1.o +#broker_module=/somewhere/module2.o arg1 arg2=3 debug=0 + + + + +# LOG ROTATION METHOD +# This is the log rotation method that Nagios should use to rotate +# the main log file. Values are as follows.. +# n = None - don't rotate the log +# h = Hourly rotation (top of the hour) +# d = Daily rotation (midnight every day) +# w = Weekly rotation (midnight on Saturday evening) +# m = Monthly rotation (midnight last day of month) + +log_rotation_method=d + + + +# LOG ARCHIVE PATH +# This is the directory where archived (rotated) log files should be +# placed (assuming you've chosen to do log rotation). + +log_archive_path=/var/log/nagios/archives + + + +# LOGGING OPTIONS +# If you want messages logged to the syslog facility, as well as the +# NetAlarm log file set this option to 1. If not, set it to 0. + +use_syslog=1 + + + +# NOTIFICATION LOGGING OPTION +# If you don't want notifications to be logged, set this value to 0. +# If notifications should be logged, set the value to 1. + +log_notifications=1 + + + +# SERVICE RETRY LOGGING OPTION +# If you don't want service check retries to be logged, set this value +# to 0. If retries should be logged, set the value to 1. + +log_service_retries=1 + + + +# HOST RETRY LOGGING OPTION +# If you don't want host check retries to be logged, set this value to +# 0. If retries should be logged, set the value to 1. + +log_host_retries=1 + + + +# EVENT HANDLER LOGGING OPTION +# If you don't want host and service event handlers to be logged, set +# this value to 0. If event handlers should be logged, set the value +# to 1. + +log_event_handlers=1 + + + +# INITIAL STATES LOGGING OPTION +# If you want Nagios to log all initial host and service states to +# the main log file (the first time the service or host is checked) +# you can enable this option by setting this value to 1. If you +# are not using an external application that does long term state +# statistics reporting, you do not need to enable this option. In +# this case, set the value to 0. + +log_initial_states=0 + + + +# EXTERNAL COMMANDS LOGGING OPTION +# If you don't want Nagios to log external commands, set this value +# to 0. If external commands should be logged, set this value to 1. +# Note: This option does not include logging of passive service +# checks - see the option below for controlling whether or not +# passive checks are logged. + +log_external_commands=1 + + + +# PASSIVE CHECKS LOGGING OPTION +# If you don't want Nagios to log passive host and service checks, set +# this value to 0. If passive checks should be logged, set +# this value to 1. + +log_passive_checks=1 + + + +# GLOBAL HOST AND SERVICE EVENT HANDLERS +# These options allow you to specify a host and service event handler +# command that is to be run for every host or service state change. +# The global event handler is executed immediately prior to the event +# handler that you have optionally specified in each host or +# service definition. The command argument is the short name of a +# command definition that you define in your host configuration file. +# Read the HTML docs for more information. + +#global_host_event_handler=somecommand +#global_service_event_handler=somecommand + + + +# SERVICE INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" service checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all service checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! This is not a +# good thing for production, but is useful when testing the +# parallelization functionality. +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +service_inter_check_delay_method=s + + + +# MAXIMUM SERVICE CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all services should +# be completed. Default is 30 minutes. + +max_service_check_spread=30 + + + +# SERVICE CHECK INTERLEAVE FACTOR +# This variable determines how service checks are interleaved. +# Interleaving the service checks allows for a more even +# distribution of service checks and reduced load on remote +# hosts. Setting this value to 1 is equivalent to how versions +# of Nagios previous to 0.0.5 did service checks. Set this +# value to s (smart) for automatic calculation of the interleave +# factor unless you have a specific reason to change it. +# s = Use "smart" interleave factor calculation +# x = Use an interleave factor of x, where x is a +# number greater than or equal to 1. + +service_interleave_factor=s + + + +# HOST INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" host checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all host checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +host_inter_check_delay_method=s + + + +# MAXIMUM HOST CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all hosts should +# be completed. Default is 30 minutes. + +max_host_check_spread=30 + + + +# MAXIMUM CONCURRENT SERVICE CHECKS +# This option allows you to specify the maximum number of +# service checks that can be run in parallel at any given time. +# Specifying a value of 1 for this variable essentially prevents +# any service checks from being parallelized. A value of 0 +# will not restrict the number of concurrent checks that are +# being executed. + +max_concurrent_checks=0 + + + +# SERVICE CHECK REAPER FREQUENCY +# This is the frequency (in seconds!) that Nagios will process +# the results of services that have been checked. + +service_reaper_frequency=10 + + + +# CHECK RESULT BUFFER SLOTS +# This settings is used to tweak the number of items or "slots" that +# the Nagios daemon should allocate to the buffer that holds +# service check results before they are processed. As check results +# are processed by the daemon, they are removed from the buffer. + +check_result_buffer_slots=4096 + + + +# AUTO-RESCHEDULING OPTION +# This option determines whether or not Nagios will attempt to +# automatically reschedule active host and service checks to +# "smooth" them out over time. This can help balance the load on +# the monitoring server. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_reschedule_checks=0 + + + +# AUTO-RESCHEDULING INTERVAL +# This option determines how often (in seconds) Nagios will +# attempt to automatically reschedule checks. This option only +# has an effect if the auto_reschedule_checks option is enabled. +# Default is 30 seconds. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_interval=30 + + + + +# AUTO-RESCHEDULING WINDOW +# This option determines the "window" of time (in seconds) that +# Nagios will look at when automatically rescheduling checks. +# Only host and service checks that occur in the next X seconds +# (determined by this variable) will be rescheduled. This option +# only has an effect if the auto_reschedule_checks option is +# enabled. Default is 180 seconds (3 minutes). +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_window=180 + + + +# SLEEP TIME +# This is the number of seconds to sleep between checking for system +# events and service checks that need to be run. + +sleep_time=0.25 + + + +# TIMEOUT VALUES +# These options control how much time Nagios will allow various +# types of commands to execute before killing them off. Options +# are available for controlling maximum time allotted for +# service checks, host checks, event handlers, notifications, the +# ocsp command, and performance data commands. All values are in +# seconds. + +service_check_timeout=60 +host_check_timeout=30 +event_handler_timeout=30 +notification_timeout=30 +ocsp_timeout=5 +perfdata_timeout=5 + + + +# RETAIN STATE INFORMATION +# This setting determines whether or not Nagios will save state +# information for services and hosts before it shuts down. Upon +# startup Nagios will reload all saved service and host state +# information before starting to monitor. This is useful for +# maintaining long-term data on state statistics, etc, but will +# slow Nagios down a bit when it (re)starts. Since its only +# a one-time penalty, I think its well worth the additional +# startup delay. + +retain_state_information=1 + + + +# STATE RETENTION FILE +# This is the file that Nagios should use to store host and +# service state information before it shuts down. The state +# information in this file is also read immediately prior to +# starting to monitor the network when Nagios is restarted. +# This file is used only if the preserve_state_information +# variable is set to 1. + +state_retention_file=/var/log/nagios/retention.dat + + + +# RETENTION DATA UPDATE INTERVAL +# This setting determines how often (in minutes) that Nagios +# will automatically save retention data during normal operation. +# If you set this value to 0, Nagios will not save retention +# data at regular interval, but it will still save retention +# data before shutting down or restarting. If you have disabled +# state retention, this option has no effect. + +retention_update_interval=60 + + + +# USE RETAINED PROGRAM STATE +# This setting determines whether or not Nagios will set +# program status variables based on the values saved in the +# retention file. If you want to use retained program status +# information, set this value to 1. If not, set this value +# to 0. + +use_retained_program_state=1 + + + +# USE RETAINED SCHEDULING INFO +# This setting determines whether or not Nagios will retain +# the scheduling info (next check time) for hosts and services +# based on the values saved in the retention file. If you +# If you want to use retained scheduling info, set this +# value to 1. If not, set this value to 0. + +use_retained_scheduling_info=0 + + + +# INTERVAL LENGTH +# This is the seconds per unit interval as used in the +# host/contact/service configuration files. Setting this to 60 means +# that each interval is one minute long (60 seconds). Other settings +# have not been tested much, so your mileage is likely to vary... + +interval_length=60 + + + +# AGGRESSIVE HOST CHECKING OPTION +# If you don't want to turn on aggressive host checking features, set +# this value to 0 (the default). Otherwise set this value to 1 to +# enable the aggressive check option. Read the docs for more info +# on what aggressive host check is or check out the source code in +# base/checks.c + +use_aggressive_host_checking=0 + + + +# SERVICE CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# service checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of service checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_service_checks=1 + + + +# PASSIVE SERVICE CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# service checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_service_checks=1 + + + +# HOST CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# host checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of host checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_host_checks=1 + + + +# PASSIVE HOST CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# host checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_host_checks=1 + + + +# NOTIFICATIONS OPTION +# This determines whether or not Nagios will sent out any host or +# service notifications when it is initially (re)started. +# Values: 1 = enable notifications, 0 = disable notifications + +enable_notifications=1 + + + +# EVENT HANDLER USE OPTION +# This determines whether or not Nagios will run any host or +# service event handlers when it is initially (re)started. Unless +# you're implementing redundant hosts, leave this option enabled. +# Values: 1 = enable event handlers, 0 = disable event handlers + +enable_event_handlers=1 + + + +# PROCESS PERFORMANCE DATA OPTION +# This determines whether or not Nagios will process performance +# data returned from service and host checks. If this option is +# enabled, host performance data will be processed using the +# host_perfdata_command (defined below) and service performance +# data will be processed using the service_perfdata_command (also +# defined below). Read the HTML docs for more information on +# performance data. +# Values: 1 = process performance data, 0 = do not process performance data + +process_performance_data=0 + + + +# HOST AND SERVICE PERFORMANCE DATA PROCESSING COMMANDS +# These commands are run after every host and service check is +# performed. These commands are executed only if the +# enable_performance_data option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on performance data. + +#host_perfdata_command=process-host-perfdata +#service_perfdata_command=process-service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILES +# These files are used to store host and service performance data. +# Performance data is only written to these files if the +# enable_performance_data option (above) is set to 1. + +#host_perfdata_file=/tmp/host-perfdata +#service_perfdata_file=/tmp/service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILE TEMPLATES +# These options determine what data is written (and how) to the +# performance data files. The templates may contain macros, special +# characters (\t for tab, \r for carriage return, \n for newline) +# and plain text. A newline is automatically added after each write +# to the performance data file. Some examples of what you can do are +# shown below. + +#host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$ +#service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$ + + + + +# HOST AND SERVICE PERFORMANCE DATA FILE MODES +# This option determines whether or not the host and service +# performance data files are opened in write ("w") or append ("a") +# mode. Unless you are the files are named pipes, you will probably +# want to use the default mode of append ("a"). + +#host_perfdata_file_mode=a +#service_perfdata_file_mode=a + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING INTERVAL +# These options determine how often (in seconds) the host and service +# performance data files are processed using the commands defined +# below. A value of 0 indicates the files should not be periodically +# processed. + +#host_perfdata_file_processing_interval=0 +#service_perfdata_file_processing_interval=0 + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING COMMANDS +# These commands are used to periodically process the host and +# service performance data files. The interval at which the +# processing occurs is determined by the options above. + +#host_perfdata_file_processing_command=process-host-perfdata-file +#service_perfdata_file_processing_command=process-service-perfdata-file + + + +# OBSESS OVER SERVICE CHECKS OPTION +# This determines whether or not Nagios will obsess over service +# checks and run the ocsp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over services, 0 = do not obsess (default) + +obsess_over_services=0 + + + +# OBSESSIVE COMPULSIVE SERVICE PROCESSOR COMMAND +# This is the command that is run for every service check that is +# processed by Nagios. This command is executed only if the +# obsess_over_service option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ocsp_command=somecommand + + + +# ORPHANED SERVICE CHECK OPTION +# This determines whether or not Nagios will periodically +# check for orphaned services. Since service checks are not +# rescheduled until the results of their previous execution +# instance are processed, there exists a possibility that some +# checks may never get rescheduled. This seems to be a rare +# problem and should not happen under normal circumstances. +# If you have problems with service checks never getting +# rescheduled, you might want to try enabling this option. +# Values: 1 = enable checks, 0 = disable checks + +check_for_orphaned_services=1 + + + +# SERVICE FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of service results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_service_freshness=1 + + + +# SERVICE FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of service check results. If you have +# disabled service freshness checking, this option has no effect. + +service_freshness_check_interval=60 + + + +# HOST FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of host results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_host_freshness=0 + + + +# HOST FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of host check results. If you have +# disabled host freshness checking, this option has no effect. + +host_freshness_check_interval=60 + + + +# AGGREGATED STATUS UPDATES +# This option determines whether or not Nagios will +# aggregate updates of host, service, and program status +# data. Normally, status data is updated immediately when +# a change occurs. This can result in high CPU loads if +# you are monitoring a lot of services. If you want Nagios +# to only refresh status data every few seconds, disable +# this option. +# Values: 1 = enable aggregate updates, 0 = disable aggregate updates + +aggregate_status_updates=1 + + + +# AGGREGATED STATUS UPDATE INTERVAL +# Combined with the aggregate_status_updates option, +# this option determines the frequency (in seconds!) that +# Nagios will periodically dump program, host, and +# service status data. If you are not using aggregated +# status data updates, this option has no effect. + +status_update_interval=15 + + + +# FLAP DETECTION OPTION +# This option determines whether or not Nagios will try +# and detect hosts and services that are "flapping". +# Flapping occurs when a host or service changes between +# states too frequently. When Nagios detects that a +# host or service is flapping, it will temporarily suppress +# notifications for that host/service until it stops +# flapping. Flap detection is very experimental, so read +# the HTML documentation before enabling this feature! +# Values: 1 = enable flap detection +# 0 = disable flap detection (default) + +enable_flap_detection=0 + + + +# FLAP DETECTION THRESHOLDS FOR HOSTS AND SERVICES +# Read the HTML documentation on flap detection for +# an explanation of what this option does. This option +# has no effect if flap detection is disabled. + +low_service_flap_threshold=5.0 +high_service_flap_threshold=20.0 +low_host_flap_threshold=5.0 +high_host_flap_threshold=20.0 + + + +# DATE FORMAT OPTION +# This option determines how short dates are displayed. Valid options +# include: +# us (MM-DD-YYYY HH:MM:SS) +# euro (DD-MM-YYYY HH:MM:SS) +# iso8601 (YYYY-MM-DD HH:MM:SS) +# strict-iso8601 (YYYY-MM-DDTHH:MM:SS) +# + +date_format=us + + + +# P1.PL FILE LOCATION +# This value determines where the p1.pl perl script (used by the +# embedded Perl interpreter) is located. If you didn't compile +# Nagios with embedded Perl support, this option has no effect. + +p1_file=/usr/sbin/p1.pl + + + +# ILLEGAL OBJECT NAME CHARACTERS +# This option allows you to specify illegal characters that cannot +# be used in host names, service descriptions, or names of other +# object types. + +illegal_object_name_chars=`~!$%^&*|'"<>?,()= + + + +# ILLEGAL MACRO OUTPUT CHARACTERS +# This option allows you to specify illegal characters that are +# stripped from macros before being used in notifications, event +# handlers, etc. This DOES NOT affect macros used in service or +# host check commands. +# The following macros are stripped of the characters you specify: +# $HOSTOUTPUT$ +# $HOSTPERFDATA$ +# $HOSTACKAUTHOR$ +# $HOSTACKCOMMENT$ +# $SERVICEOUTPUT$ +# $SERVICEPERFDATA$ +# $SERVICEACKAUTHOR$ +# $SERVICEACKCOMMENT$ + +illegal_macro_output_chars=`~$&|'"<> + + + +# REGULAR EXPRESSION MATCHING +# This option controls whether or not regular expression matching +# takes place in the object config files. Regular expression +# matching is used to match host, hostgroup, service, and service +# group names/descriptions in some fields of various object types. +# Values: 1 = enable regexp matching, 0 = disable regexp matching + +use_regexp_matching=0 + + + +# "TRUE" REGULAR EXPRESSION MATCHING +# This option controls whether or not "true" regular expression +# matching takes place in the object config files. This option +# only has an effect if regular expression matching is enabled +# (see above). If this option is DISABLED, regular expression +# matching only occurs if a string contains wildcard characters +# (* and ?). If the option is ENABLED, regexp matching occurs +# all the time (which can be annoying). +# Values: 1 = enable true matching, 0 = disable true matching + +use_true_regexp_matching=0 + + + + +# ADMINISTRATOR EMAIL ADDRESS +# The email address of the administrator of *this* machine (the one +# doing the monitoring). Nagios never uses this value itself, but +# you can access this value by using the $ADMINEMAIL$ macro in your +# notification commands. + +admin_email=nagios + + + +# ADMINISTRATOR PAGER NUMBER/ADDRESS +# The pager number/address for the administrator of *this* machine. +# Nagios never uses this value itself, but you can access this +# value by using the $ADMINPAGER$ macro in your notification +# commands. + +admin_pager=pagenagios + + + +# DAEMON CORE DUMP OPTION +# This option determines whether or not Nagios is allowed to create +# a core dump when it runs as a daemon. Note that it is generally +# considered bad form to allow this, but it may be useful for +# debugging purposes. +# Values: 1 - Allow core dumps +# 0 - Do not allow core dumps (default) + +daemon_dumps_core=0 + + + diff --git a/puppet/modules/nagios/files/configs/CentOS/private/resource.cfg.i386 b/puppet/modules/nagios/files/configs/CentOS/private/resource.cfg.i386 new file mode 100644 index 00000000..0ccf2e17 --- /dev/null +++ b/puppet/modules/nagios/files/configs/CentOS/private/resource.cfg.i386 @@ -0,0 +1,34 @@ +########################################################################### +# +# RESOURCE.CFG - Sample Resource File for Nagios 2.9 +# +# Last Modified: 09-10-2003 +# +# You can define $USERx$ macros in this file, which can in turn be used +# in command definitions in your host config file(s). $USERx$ macros are +# useful for storing sensitive information such as usernames, passwords, +# etc. They are also handy for specifying the path to plugins and +# event handlers - if you decide to move the plugins or event handlers to +# a different directory in the future, you can just update one or two +# $USERx$ macros, instead of modifying a lot of command definitions. +# +# The CGIs will not attempt to read the contents of resource files, so +# you can set restrictive permissions (600 or 660) on them. +# +# Nagios supports up to 32 $USERx$ macros ($USER1$ through $USER32$) +# +# Resource files may also be used to store configuration directives for +# external data sources like MySQL... +# +########################################################################### + +# Sets $USER1$ to be the path to the plugins +$USER1$=/usr/lib/nagios/plugins + +# Sets $USER2$ to be the path to event handlers +#$USER2$=/usr/lib64/nagios/plugins/eventhandlers + +# Store some usernames and passwords (hidden from the CGIs) +#$USER3$=someuser +#$USER4$=somepassword + diff --git a/puppet/modules/nagios/files/configs/CentOS/private/resource.cfg.x86_64 b/puppet/modules/nagios/files/configs/CentOS/private/resource.cfg.x86_64 new file mode 100644 index 00000000..b9f0841c --- /dev/null +++ b/puppet/modules/nagios/files/configs/CentOS/private/resource.cfg.x86_64 @@ -0,0 +1,34 @@ +########################################################################### +# +# RESOURCE.CFG - Sample Resource File for Nagios 2.9 +# +# Last Modified: 09-10-2003 +# +# You can define $USERx$ macros in this file, which can in turn be used +# in command definitions in your host config file(s). $USERx$ macros are +# useful for storing sensitive information such as usernames, passwords, +# etc. They are also handy for specifying the path to plugins and +# event handlers - if you decide to move the plugins or event handlers to +# a different directory in the future, you can just update one or two +# $USERx$ macros, instead of modifying a lot of command definitions. +# +# The CGIs will not attempt to read the contents of resource files, so +# you can set restrictive permissions (600 or 660) on them. +# +# Nagios supports up to 32 $USERx$ macros ($USER1$ through $USER32$) +# +# Resource files may also be used to store configuration directives for +# external data sources like MySQL... +# +########################################################################### + +# Sets $USER1$ to be the path to the plugins +$USER1$=/usr/lib64/nagios/plugins + +# Sets $USER2$ to be the path to event handlers +#$USER2$=/usr/lib64/nagios/plugins/eventhandlers + +# Store some usernames and passwords (hidden from the CGIs) +#$USER3$=someuser +#$USER4$=somepassword + diff --git a/puppet/modules/nagios/files/configs/Debian/cgi.cfg b/puppet/modules/nagios/files/configs/Debian/cgi.cfg new file mode 100644 index 00000000..103db8a1 --- /dev/null +++ b/puppet/modules/nagios/files/configs/Debian/cgi.cfg @@ -0,0 +1,330 @@ +################################################################# +# +# CGI.CFG - Sample CGI Configuration File for Nagios +# +################################################################# + + +# MAIN CONFIGURATION FILE +# This tells the CGIs where to find your main configuration file. +# The CGIs will read the main and host config files for any other +# data they might need. + +main_config_file=/etc/nagios3/nagios.cfg + + + +# PHYSICAL HTML PATH +# This is the path where the HTML files for Nagios reside. This +# value is used to locate the logo images needed by the statusmap +# and statuswrl CGIs. + +physical_html_path=/usr/share/nagios3/htdocs + + + +# URL HTML PATH +# This is the path portion of the URL that corresponds to the +# physical location of the Nagios HTML files (as defined above). +# This value is used by the CGIs to locate the online documentation +# and graphics. If you access the Nagios pages with an URL like +# http://www.myhost.com/nagios, this value should be '/nagios' +# (without the quotes). + +url_html_path=/nagios3 + + + +# CONTEXT-SENSITIVE HELP +# This option determines whether or not a context-sensitive +# help icon will be displayed for most of the CGIs. +# Values: 0 = disables context-sensitive help +# 1 = enables context-sensitive help + +show_context_help=1 + + + +# PENDING STATES OPTION +# This option determines what states should be displayed in the web +# interface for hosts/services that have not yet been checked. +# Values: 0 = leave hosts/services that have not been check yet in their original state +# 1 = mark hosts/services that have not been checked yet as PENDING + +use_pending_states=1 + +nagios_check_command=/usr/lib/nagios/plugins/check_nagios /var/cache/nagios3/status.dat 5 '/usr/sbin/nagios3' + + +# AUTHENTICATION USAGE +# This option controls whether or not the CGIs will use any +# authentication when displaying host and service information, as +# well as committing commands to Nagios for processing. +# +# Read the HTML documentation to learn how the authorization works! +# +# NOTE: It is a really *bad* idea to disable authorization, unless +# you plan on removing the command CGI (cmd.cgi)! Failure to do +# so will leave you wide open to kiddies messing with Nagios and +# possibly hitting you with a denial of service attack by filling up +# your drive by continuously writing to your command file! +# +# Setting this value to 0 will cause the CGIs to *not* use +# authentication (bad idea), while any other value will make them +# use the authentication functions (the default). + +use_authentication=1 + + + + +# x509 CERT AUTHENTICATION +# When enabled, this option allows you to use x509 cert (SSL) +# authentication in the CGIs. This is an advanced option and should +# not be enabled unless you know what you're doing. + +use_ssl_authentication=0 + + + + +# DEFAULT USER +# Setting this variable will define a default user name that can +# access pages without authentication. This allows people within a +# secure domain (i.e., behind a firewall) to see the current status +# without authenticating. You may want to use this to avoid basic +# authentication if you are not using a secure server since basic +# authentication transmits passwords in the clear. +# +# Important: Do not define a default username unless you are +# running a secure web server and are sure that everyone who has +# access to the CGIs has been authenticated in some manner! If you +# define this variable, anyone who has not authenticated to the web +# server will inherit all rights you assign to this user! + +#default_user_name=guest + + + +# SYSTEM/PROCESS INFORMATION ACCESS +# This option is a comma-delimited list of all usernames that +# have access to viewing the Nagios process information as +# provided by the Extended Information CGI (extinfo.cgi). By +# default, *no one* has access to this unless you choose to +# not use authorization. You may use an asterisk (*) to +# authorize any user who has authenticated to the web server. + +authorized_for_system_information=nagiosadmin + + + +# CONFIGURATION INFORMATION ACCESS +# This option is a comma-delimited list of all usernames that +# can view ALL configuration information (hosts, commands, etc). +# By default, users can only view configuration information +# for the hosts and services they are contacts for. You may use +# an asterisk (*) to authorize any user who has authenticated +# to the web server. + +authorized_for_configuration_information=nagiosadmin + + + +# SYSTEM/PROCESS COMMAND ACCESS +# This option is a comma-delimited list of all usernames that +# can issue shutdown and restart commands to Nagios via the +# command CGI (cmd.cgi). Users in this list can also change +# the program mode to active or standby. By default, *no one* +# has access to this unless you choose to not use authorization. +# You may use an asterisk (*) to authorize any user who has +# authenticated to the web server. + +authorized_for_system_commands=nagiosadmin + + + +# GLOBAL HOST/SERVICE VIEW ACCESS +# These two options are comma-delimited lists of all usernames that +# can view information for all hosts and services that are being +# monitored. By default, users can only view information +# for hosts or services that they are contacts for (unless you +# you choose to not use authorization). You may use an asterisk (*) +# to authorize any user who has authenticated to the web server. + + +authorized_for_all_services=nagiosadmin +authorized_for_all_hosts=nagiosadmin + + + +# GLOBAL HOST/SERVICE COMMAND ACCESS +# These two options are comma-delimited lists of all usernames that +# can issue host or service related commands via the command +# CGI (cmd.cgi) for all hosts and services that are being monitored. +# By default, users can only issue commands for hosts or services +# that they are contacts for (unless you you choose to not use +# authorization). You may use an asterisk (*) to authorize any +# user who has authenticated to the web server. + +authorized_for_all_service_commands=nagiosadmin +authorized_for_all_host_commands=nagiosadmin + + + + +# STATUSMAP BACKGROUND IMAGE +# This option allows you to specify an image to be used as a +# background in the statusmap CGI. It is assumed that the image +# resides in the HTML images path (i.e. /usr/local/nagios/share/images). +# This path is automatically determined by appending "/images" +# to the path specified by the 'physical_html_path' directive. +# Note: The image file may be in GIF, PNG, JPEG, or GD2 format. +# However, I recommend that you convert your image to GD2 format +# (uncompressed), as this will cause less CPU load when the CGI +# generates the image. + +#statusmap_background_image=smbackground.gd2 + + + +# DEFAULT STATUSMAP LAYOUT METHOD +# This option allows you to specify the default layout method +# the statusmap CGI should use for drawing hosts. If you do +# not use this option, the default is to use user-defined +# coordinates. Valid options are as follows: +# 0 = User-defined coordinates +# 1 = Depth layers +# 2 = Collapsed tree +# 3 = Balanced tree +# 4 = Circular +# 5 = Circular (Marked Up) + +default_statusmap_layout=5 + + + +# DEFAULT STATUSWRL LAYOUT METHOD +# This option allows you to specify the default layout method +# the statuswrl (VRML) CGI should use for drawing hosts. If you +# do not use this option, the default is to use user-defined +# coordinates. Valid options are as follows: +# 0 = User-defined coordinates +# 2 = Collapsed tree +# 3 = Balanced tree +# 4 = Circular + +default_statuswrl_layout=4 + + + +# STATUSWRL INCLUDE +# This option allows you to include your own objects in the +# generated VRML world. It is assumed that the file +# resides in the HTML path (i.e. /usr/local/nagios/share). + +#statuswrl_include=myworld.wrl + + + +# PING SYNTAX +# This option determines what syntax should be used when +# attempting to ping a host from the WAP interface (using +# the statuswml CGI. You must include the full path to +# the ping binary, along with all required options. The +# $HOSTADDRESS$ macro is substituted with the address of +# the host before the command is executed. +# Please note that the syntax for the ping binary is +# notorious for being different on virtually ever *NIX +# OS and distribution, so you may have to tweak this to +# work on your system. + +ping_syntax=/bin/ping -n -U -c 5 $HOSTADDRESS$ + + + +# REFRESH RATE +# This option allows you to specify the refresh rate in seconds +# of various CGIs (status, statusmap, extinfo, and outages). + +refresh_rate=90 + + + +# ESCAPE HTML TAGS +# This option determines whether HTML tags in host and service +# status output is escaped in the web interface. If enabled, +# your plugin output will not be able to contain clickable links. + +escape_html_tags=1 + + + + +# SOUND OPTIONS +# These options allow you to specify an optional audio file +# that should be played in your browser window when there are +# problems on the network. The audio files are used only in +# the status CGI. Only the sound for the most critical problem +# will be played. Order of importance (higher to lower) is as +# follows: unreachable hosts, down hosts, critical services, +# warning services, and unknown services. If there are no +# visible problems, the sound file optionally specified by +# 'normal_sound' variable will be played. +# +# +# <varname>=<sound_file> +# +# Note: All audio files must be placed in the /media subdirectory +# under the HTML path (i.e. /usr/local/nagios/share/media/). + +#host_unreachable_sound=hostdown.wav +#host_down_sound=hostdown.wav +#service_critical_sound=critical.wav +#service_warning_sound=warning.wav +#service_unknown_sound=warning.wav +#normal_sound=noproblem.wav + + + +# URL TARGET FRAMES +# These options determine the target frames in which notes and +# action URLs will open. + +action_url_target=_blank +notes_url_target=_blank + + + + +# LOCK AUTHOR NAMES OPTION +# This option determines whether users can change the author name +# when submitting comments, scheduling downtime. If disabled, the +# author names will be locked into their contact name, as defined in Nagios. +# Values: 0 = allow editing author names +# 1 = lock author names (disallow editing) + +lock_author_names=1 + + + + +# SPLUNK INTEGRATION OPTIONS +# These options allow you to enable integration with Splunk +# in the web interface. If enabled, you'll be presented with +# "Splunk It" links in various places in the CGIs (log file, +# alert history, host/service detail, etc). Useful if you're +# trying to research why a particular problem occurred. +# For more information on Splunk, visit http://www.splunk.com/ + +# This option determines whether the Splunk integration is enabled +# Values: 0 = disable Splunk integration +# 1 = enable Splunk integration + +#enable_splunk_integration=1 + + +# This option should be the URL used to access your instance of Splunk + +#splunk_url=http://127.0.0.1:8000/ + + diff --git a/puppet/modules/nagios/files/configs/Debian/nagios.cfg b/puppet/modules/nagios/files/configs/Debian/nagios.cfg new file mode 100644 index 00000000..291a4741 --- /dev/null +++ b/puppet/modules/nagios/files/configs/Debian/nagios.cfg @@ -0,0 +1,1288 @@ +############################################################################## +# +# NAGIOS.CFG - Sample Main Config File for Nagios +# +# +############################################################################## + + +# LOG FILE +# This is the main log file where service and host events are logged +# for historical purposes. This should be the first option specified +# in the config file!!! + +log_file=/var/log/nagios3/nagios.log + + + +# OBJECT CONFIGURATION FILE(S) +# These are the object configuration files in which you define hosts, +# host groups, contacts, contact groups, services, etc. +# You can split your object definitions across several config files +# if you wish (as shown below), or keep them all in a single config file. +#cfg_file=/etc/nagios3/commands.cfg + +# Puppet-managed configuration files +cfg_file=/etc/nagios3/nagios_templates.cfg +cfg_file=/etc/nagios3/nagios_command.cfg +cfg_file=/etc/nagios3/nagios_contact.cfg +cfg_file=/etc/nagios3/nagios_contactgroup.cfg +cfg_file=/etc/nagios3/nagios_host.cfg +cfg_file=/etc/nagios3/nagios_hostdependency.cfg +cfg_file=/etc/nagios3/nagios_hostescalation.cfg +cfg_file=/etc/nagios3/nagios_hostextinfo.cfg +cfg_file=/etc/nagios3/nagios_hostgroup.cfg +cfg_file=/etc/nagios3/nagios_hostgroupescalation.cfg +cfg_file=/etc/nagios3/nagios_service.cfg +cfg_file=/etc/nagios3/nagios_servicedependency.cfg +cfg_file=/etc/nagios3/nagios_serviceescalation.cfg +cfg_file=/etc/nagios3/nagios_serviceextinfo.cfg +cfg_file=/etc/nagios3/nagios_servicegroup.cfg +cfg_file=/etc/nagios3/nagios_timeperiod.cfg + +# Debian also defaults to using the check commands defined by the debian +# nagios-plugins package +cfg_dir=/etc/nagios-plugins/config + + + +# OBJECT CACHE FILE +# This option determines where object definitions are cached when +# Nagios starts/restarts. The CGIs read object definitions from +# this cache file (rather than looking at the object config files +# directly) in order to prevent inconsistencies that can occur +# when the config files are modified after Nagios starts. + +object_cache_file=/var/cache/nagios3/objects.cache + + + +# PRE-CACHED OBJECT FILE +# This options determines the location of the precached object file. +# If you run Nagios with the -p command line option, it will preprocess +# your object configuration file(s) and write the cached config to this +# file. You can then start Nagios with the -u option to have it read +# object definitions from this precached file, rather than the standard +# object configuration files (see the cfg_file and cfg_dir options above). +# Using a precached object file can speed up the time needed to (re)start +# the Nagios process if you've got a large and/or complex configuration. +# Read the documentation section on optimizing Nagios to find our more +# about how this feature works. + +precached_object_file=/var/lib/nagios3/objects.precache + + + +# RESOURCE FILE +# This is an optional resource file that contains $USERx$ macro +# definitions. Multiple resource files can be specified by using +# multiple resource_file definitions. The CGIs will not attempt to +# read the contents of resource files, so information that is +# considered to be sensitive (usernames, passwords, etc) can be +# defined as macros in this file and restrictive permissions (600) +# can be placed on this file. + +resource_file=/etc/nagios3/resource.cfg + + + +# STATUS FILE +# This is where the current status of all monitored services and +# hosts is stored. Its contents are read and processed by the CGIs. +# The contents of the status file are deleted every time Nagios +# restarts. + +status_file=/var/cache/nagios3/status.dat + + + +# STATUS FILE UPDATE INTERVAL +# This option determines the frequency (in seconds) that +# Nagios will periodically dump program, host, and +# service status data. + +status_update_interval=10 + + + +# NAGIOS USER +# This determines the effective user that Nagios should run as. +# You can either supply a username or a UID. + +nagios_user=nagios + + + +# NAGIOS GROUP +# This determines the effective group that Nagios should run as. +# You can either supply a group name or a GID. + +nagios_group=nagios + + + +# EXTERNAL COMMAND OPTION +# This option allows you to specify whether or not Nagios should check +# for external commands (in the command file defined below). By default +# Nagios will *not* check for external commands, just to be on the +# cautious side. If you want to be able to use the CGI command interface +# you will have to enable this. +# Values: 0 = disable commands, 1 = enable commands + +check_external_commands=0 + + + +# EXTERNAL COMMAND CHECK INTERVAL +# This is the interval at which Nagios should check for external commands. +# This value works of the interval_length you specify later. If you leave +# that at its default value of 60 (seconds), a value of 1 here will cause +# Nagios to check for external commands every minute. If you specify a +# number followed by an "s" (i.e. 15s), this will be interpreted to mean +# actual seconds rather than a multiple of the interval_length variable. +# Note: In addition to reading the external command file at regularly +# scheduled intervals, Nagios will also check for external commands after +# event handlers are executed. +# NOTE: Setting this value to -1 causes Nagios to check the external +# command file as often as possible. + +#command_check_interval=15s +command_check_interval=-1 + + + +# EXTERNAL COMMAND FILE +# This is the file that Nagios checks for external command requests. +# It is also where the command CGI will write commands that are submitted +# by users, so it must be writeable by the user that the web server +# is running as (usually 'nobody'). Permissions should be set at the +# directory level instead of on the file, as the file is deleted every +# time its contents are processed. +# Debian Users: In case you didn't read README.Debian yet, _NOW_ is the +# time to do it. + +command_file=/var/lib/nagios3/rw/nagios.cmd + + + +# EXTERNAL COMMAND BUFFER SLOTS +# This settings is used to tweak the number of items or "slots" that +# the Nagios daemon should allocate to the buffer that holds incoming +# external commands before they are processed. As external commands +# are processed by the daemon, they are removed from the buffer. + +external_command_buffer_slots=4096 + + + +# LOCK FILE +# This is the lockfile that Nagios will use to store its PID number +# in when it is running in daemon mode. + +lock_file=/var/run/nagios3/nagios3.pid + + + +# TEMP FILE +# This is a temporary file that is used as scratch space when Nagios +# updates the status log, cleans the comment file, etc. This file +# is created, used, and deleted throughout the time that Nagios is +# running. + +temp_file=/var/cache/nagios3/nagios.tmp + + + +# TEMP PATH +# This is path where Nagios can create temp files for service and +# host check results, etc. + +temp_path=/tmp + + + +# EVENT BROKER OPTIONS +# Controls what (if any) data gets sent to the event broker. +# Values: 0 = Broker nothing +# -1 = Broker everything +# <other> = See documentation + +event_broker_options=-1 + + + +# EVENT BROKER MODULE(S) +# This directive is used to specify an event broker module that should +# by loaded by Nagios at startup. Use multiple directives if you want +# to load more than one module. Arguments that should be passed to +# the module at startup are seperated from the module path by a space. +# +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# +# Do NOT overwrite modules while they are being used by Nagios or Nagios +# will crash in a fiery display of SEGFAULT glory. This is a bug/limitation +# either in dlopen(), the kernel, and/or the filesystem. And maybe Nagios... +# +# The correct/safe way of updating a module is by using one of these methods: +# 1. Shutdown Nagios, replace the module file, restart Nagios +# 2. Delete the original module file, move the new module file into place, restart Nagios +# +# Example: +# +# broker_module=<modulepath> [moduleargs] + +#broker_module=/somewhere/module1.o +#broker_module=/somewhere/module2.o arg1 arg2=3 debug=0 + + + +# LOG ROTATION METHOD +# This is the log rotation method that Nagios should use to rotate +# the main log file. Values are as follows.. +# n = None - don't rotate the log +# h = Hourly rotation (top of the hour) +# d = Daily rotation (midnight every day) +# w = Weekly rotation (midnight on Saturday evening) +# m = Monthly rotation (midnight last day of month) + +log_rotation_method=d + + + +# LOG ARCHIVE PATH +# This is the directory where archived (rotated) log files should be +# placed (assuming you've chosen to do log rotation). + +log_archive_path=/var/log/nagios3/archives + + + +# LOGGING OPTIONS +# If you want messages logged to the syslog facility, as well as the +# Nagios log file set this option to 1. If not, set it to 0. + +use_syslog=1 + + + +# NOTIFICATION LOGGING OPTION +# If you don't want notifications to be logged, set this value to 0. +# If notifications should be logged, set the value to 1. + +log_notifications=1 + + + +# SERVICE RETRY LOGGING OPTION +# If you don't want service check retries to be logged, set this value +# to 0. If retries should be logged, set the value to 1. + +log_service_retries=1 + + + +# HOST RETRY LOGGING OPTION +# If you don't want host check retries to be logged, set this value to +# 0. If retries should be logged, set the value to 1. + +log_host_retries=1 + + + +# EVENT HANDLER LOGGING OPTION +# If you don't want host and service event handlers to be logged, set +# this value to 0. If event handlers should be logged, set the value +# to 1. + +log_event_handlers=1 + + + +# INITIAL STATES LOGGING OPTION +# If you want Nagios to log all initial host and service states to +# the main log file (the first time the service or host is checked) +# you can enable this option by setting this value to 1. If you +# are not using an external application that does long term state +# statistics reporting, you do not need to enable this option. In +# this case, set the value to 0. + +log_initial_states=0 + + + +# EXTERNAL COMMANDS LOGGING OPTION +# If you don't want Nagios to log external commands, set this value +# to 0. If external commands should be logged, set this value to 1. +# Note: This option does not include logging of passive service +# checks - see the option below for controlling whether or not +# passive checks are logged. + +log_external_commands=1 + + + +# PASSIVE CHECKS LOGGING OPTION +# If you don't want Nagios to log passive host and service checks, set +# this value to 0. If passive checks should be logged, set +# this value to 1. + +log_passive_checks=1 + + + +# GLOBAL HOST AND SERVICE EVENT HANDLERS +# These options allow you to specify a host and service event handler +# command that is to be run for every host or service state change. +# The global event handler is executed immediately prior to the event +# handler that you have optionally specified in each host or +# service definition. The command argument is the short name of a +# command definition that you define in your host configuration file. +# Read the HTML docs for more information. + +#global_host_event_handler=somecommand +#global_service_event_handler=somecommand + + + +# SERVICE INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" service checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all service checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! This is not a +# good thing for production, but is useful when testing the +# parallelization functionality. +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +service_inter_check_delay_method=s + + + +# MAXIMUM SERVICE CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all services should +# be completed. Default is 30 minutes. + +max_service_check_spread=30 + + + +# SERVICE CHECK INTERLEAVE FACTOR +# This variable determines how service checks are interleaved. +# Interleaving the service checks allows for a more even +# distribution of service checks and reduced load on remote +# hosts. Setting this value to 1 is equivalent to how versions +# of Nagios previous to 0.0.5 did service checks. Set this +# value to s (smart) for automatic calculation of the interleave +# factor unless you have a specific reason to change it. +# s = Use "smart" interleave factor calculation +# x = Use an interleave factor of x, where x is a +# number greater than or equal to 1. + +service_interleave_factor=s + + + +# HOST INTER-CHECK DELAY METHOD +# This is the method that Nagios should use when initially +# "spreading out" host checks when it starts monitoring. The +# default is to use smart delay calculation, which will try to +# space all host checks out evenly to minimize CPU load. +# Using the dumb setting will cause all checks to be scheduled +# at the same time (with no delay between them)! +# n = None - don't use any delay between checks +# d = Use a "dumb" delay of 1 second between checks +# s = Use "smart" inter-check delay calculation +# x.xx = Use an inter-check delay of x.xx seconds + +host_inter_check_delay_method=s + + + +# MAXIMUM HOST CHECK SPREAD +# This variable determines the timeframe (in minutes) from the +# program start time that an initial check of all hosts should +# be completed. Default is 30 minutes. + +max_host_check_spread=30 + + + +# MAXIMUM CONCURRENT SERVICE CHECKS +# This option allows you to specify the maximum number of +# service checks that can be run in parallel at any given time. +# Specifying a value of 1 for this variable essentially prevents +# any service checks from being parallelized. A value of 0 +# will not restrict the number of concurrent checks that are +# being executed. + +max_concurrent_checks=0 + + + +# HOST AND SERVICE CHECK REAPER FREQUENCY +# This is the frequency (in seconds!) that Nagios will process +# the results of host and service checks. + +check_result_reaper_frequency=10 + + + + +# MAX CHECK RESULT REAPER TIME +# This is the max amount of time (in seconds) that a single +# check result reaper event will be allowed to run before +# returning control back to Nagios so it can perform other +# duties. + +max_check_result_reaper_time=30 + + + + +# CHECK RESULT PATH +# This is directory where Nagios stores the results of host and +# service checks that have not yet been processed. +# +# Note: Make sure that only one instance of Nagios has access +# to this directory! + +check_result_path=/var/lib/nagios3/spool/checkresults + + + + +# MAX CHECK RESULT FILE AGE +# This option determines the maximum age (in seconds) which check +# result files are considered to be valid. Files older than this +# threshold will be mercilessly deleted without further processing. + +max_check_result_file_age=3600 + + + + +# CACHED HOST CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous host check is considered current. +# Cached host states (from host checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to the host check logic. +# Too high of a value for this option may result in inaccurate host +# states being used by Nagios, while a lower value may result in a +# performance hit for host checks. Use a value of 0 to disable host +# check caching. + +cached_host_check_horizon=15 + + + +# CACHED SERVICE CHECK HORIZON +# This option determines the maximum amount of time (in seconds) +# that the state of a previous service check is considered current. +# Cached service states (from service checks that were performed more +# recently that the timeframe specified by this value) can immensely +# improve performance in regards to predictive dependency checks. +# Use a value of 0 to disable service check caching. + +cached_service_check_horizon=15 + + + +# ENABLE PREDICTIVE HOST DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of hosts when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# host dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_host_dependency_checks=1 + + + +# ENABLE PREDICTIVE SERVICE DEPENDENCY CHECKS +# This option determines whether or not Nagios will attempt to execute +# checks of service when it predicts that future dependency logic test +# may be needed. These predictive checks can help ensure that your +# service dependency logic works well. +# Values: +# 0 = Disable predictive checks +# 1 = Enable predictive checks (default) + +enable_predictive_service_dependency_checks=1 + + + +# SOFT STATE DEPENDENCIES +# This option determines whether or not Nagios will use soft state +# information when checking host and service dependencies. Normally +# Nagios will only use the latest hard host or service state when +# checking dependencies. If you want it to use the latest state (regardless +# of whether its a soft or hard state type), enable this option. +# Values: +# 0 = Don't use soft state dependencies (default) +# 1 = Use soft state dependencies + +soft_state_dependencies=0 + + + +# TIME CHANGE ADJUSTMENT THRESHOLDS +# These options determine when Nagios will react to detected changes +# in system time (either forward or backwards). + +#time_change_threshold=900 + + + +# AUTO-RESCHEDULING OPTION +# This option determines whether or not Nagios will attempt to +# automatically reschedule active host and service checks to +# "smooth" them out over time. This can help balance the load on +# the monitoring server. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_reschedule_checks=0 + + + +# AUTO-RESCHEDULING INTERVAL +# This option determines how often (in seconds) Nagios will +# attempt to automatically reschedule checks. This option only +# has an effect if the auto_reschedule_checks option is enabled. +# Default is 30 seconds. +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_interval=30 + + + +# AUTO-RESCHEDULING WINDOW +# This option determines the "window" of time (in seconds) that +# Nagios will look at when automatically rescheduling checks. +# Only host and service checks that occur in the next X seconds +# (determined by this variable) will be rescheduled. This option +# only has an effect if the auto_reschedule_checks option is +# enabled. Default is 180 seconds (3 minutes). +# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE +# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY + +auto_rescheduling_window=180 + + + +# SLEEP TIME +# This is the number of seconds to sleep between checking for system +# events and service checks that need to be run. + +sleep_time=0.25 + + + +# TIMEOUT VALUES +# These options control how much time Nagios will allow various +# types of commands to execute before killing them off. Options +# are available for controlling maximum time allotted for +# service checks, host checks, event handlers, notifications, the +# ocsp command, and performance data commands. All values are in +# seconds. + +service_check_timeout=60 +host_check_timeout=30 +event_handler_timeout=30 +notification_timeout=30 +ocsp_timeout=5 +perfdata_timeout=5 + + + +# RETAIN STATE INFORMATION +# This setting determines whether or not Nagios will save state +# information for services and hosts before it shuts down. Upon +# startup Nagios will reload all saved service and host state +# information before starting to monitor. This is useful for +# maintaining long-term data on state statistics, etc, but will +# slow Nagios down a bit when it (re)starts. Since its only +# a one-time penalty, I think its well worth the additional +# startup delay. + +retain_state_information=1 + + + +# STATE RETENTION FILE +# This is the file that Nagios should use to store host and +# service state information before it shuts down. The state +# information in this file is also read immediately prior to +# starting to monitor the network when Nagios is restarted. +# This file is used only if the preserve_state_information +# variable is set to 1. + +state_retention_file=/var/lib/nagios3/retention.dat + + + +# RETENTION DATA UPDATE INTERVAL +# This setting determines how often (in minutes) that Nagios +# will automatically save retention data during normal operation. +# If you set this value to 0, Nagios will not save retention +# data at regular interval, but it will still save retention +# data before shutting down or restarting. If you have disabled +# state retention, this option has no effect. + +retention_update_interval=60 + + + +# USE RETAINED PROGRAM STATE +# This setting determines whether or not Nagios will set +# program status variables based on the values saved in the +# retention file. If you want to use retained program status +# information, set this value to 1. If not, set this value +# to 0. + +use_retained_program_state=1 + + + +# USE RETAINED SCHEDULING INFO +# This setting determines whether or not Nagios will retain +# the scheduling info (next check time) for hosts and services +# based on the values saved in the retention file. If you +# If you want to use retained scheduling info, set this +# value to 1. If not, set this value to 0. + +use_retained_scheduling_info=1 + + + +# RETAINED ATTRIBUTE MASKS (ADVANCED FEATURE) +# The following variables are used to specify specific host and +# service attributes that should *not* be retained by Nagios during +# program restarts. +# +# The values of the masks are bitwise ANDs of values specified +# by the "MODATTR_" definitions found in include/common.h. +# For example, if you do not want the current enabled/disabled state +# of flap detection and event handlers for hosts to be retained, you +# would use a value of 24 for the host attribute mask... +# MODATTR_EVENT_HANDLER_ENABLED (8) + MODATTR_FLAP_DETECTION_ENABLED (16) = 24 + +# This mask determines what host attributes are not retained +retained_host_attribute_mask=0 + +# This mask determines what service attributes are not retained +retained_service_attribute_mask=0 + +# These two masks determine what process attributes are not retained. +# There are two masks, because some process attributes have host and service +# options. For example, you can disable active host checks, but leave active +# service checks enabled. +retained_process_host_attribute_mask=0 +retained_process_service_attribute_mask=0 + +# These two masks determine what contact attributes are not retained. +# There are two masks, because some contact attributes have host and +# service options. For example, you can disable host notifications for +# a contact, but leave service notifications enabled for them. +retained_contact_host_attribute_mask=0 +retained_contact_service_attribute_mask=0 + + + +# INTERVAL LENGTH +# This is the seconds per unit interval as used in the +# host/contact/service configuration files. Setting this to 60 means +# that each interval is one minute long (60 seconds). Other settings +# have not been tested much, so your mileage is likely to vary... + +interval_length=60 + + + +# AGGRESSIVE HOST CHECKING OPTION +# If you don't want to turn on aggressive host checking features, set +# this value to 0 (the default). Otherwise set this value to 1 to +# enable the aggressive check option. Read the docs for more info +# on what aggressive host check is or check out the source code in +# base/checks.c + +use_aggressive_host_checking=0 + + + +# SERVICE CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# service checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of service checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_service_checks=1 + + + +# PASSIVE SERVICE CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# service checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_service_checks=1 + + + +# HOST CHECK EXECUTION OPTION +# This determines whether or not Nagios will actively execute +# host checks when it initially starts. If this option is +# disabled, checks are not actively made, but Nagios can still +# receive and process passive check results that come in. Unless +# you're implementing redundant hosts or have a special need for +# disabling the execution of host checks, leave this enabled! +# Values: 1 = enable checks, 0 = disable checks + +execute_host_checks=1 + + + +# PASSIVE HOST CHECK ACCEPTANCE OPTION +# This determines whether or not Nagios will accept passive +# host checks results when it initially (re)starts. +# Values: 1 = accept passive checks, 0 = reject passive checks + +accept_passive_host_checks=1 + + + +# NOTIFICATIONS OPTION +# This determines whether or not Nagios will sent out any host or +# service notifications when it is initially (re)started. +# Values: 1 = enable notifications, 0 = disable notifications + +enable_notifications=1 + + + +# EVENT HANDLER USE OPTION +# This determines whether or not Nagios will run any host or +# service event handlers when it is initially (re)started. Unless +# you're implementing redundant hosts, leave this option enabled. +# Values: 1 = enable event handlers, 0 = disable event handlers + +enable_event_handlers=1 + + + +# PROCESS PERFORMANCE DATA OPTION +# This determines whether or not Nagios will process performance +# data returned from service and host checks. If this option is +# enabled, host performance data will be processed using the +# host_perfdata_command (defined below) and service performance +# data will be processed using the service_perfdata_command (also +# defined below). Read the HTML docs for more information on +# performance data. +# Values: 1 = process performance data, 0 = do not process performance data + +process_performance_data=0 + + + +# HOST AND SERVICE PERFORMANCE DATA PROCESSING COMMANDS +# These commands are run after every host and service check is +# performed. These commands are executed only if the +# enable_performance_data option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on performance data. + +#host_perfdata_command=process-host-perfdata +#service_perfdata_command=process-service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILES +# These files are used to store host and service performance data. +# Performance data is only written to these files if the +# enable_performance_data option (above) is set to 1. + +#host_perfdata_file=/tmp/host-perfdata +#service_perfdata_file=/tmp/service-perfdata + + + +# HOST AND SERVICE PERFORMANCE DATA FILE TEMPLATES +# These options determine what data is written (and how) to the +# performance data files. The templates may contain macros, special +# characters (\t for tab, \r for carriage return, \n for newline) +# and plain text. A newline is automatically added after each write +# to the performance data file. Some examples of what you can do are +# shown below. + +#host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$ +#service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$ + + + +# HOST AND SERVICE PERFORMANCE DATA FILE MODES +# This option determines whether or not the host and service +# performance data files are opened in write ("w") or append ("a") +# mode. If you want to use named pipes, you should use the special +# pipe ("p") mode which avoid blocking at startup, otherwise you will +# likely want the defult append ("a") mode. + +#host_perfdata_file_mode=a +#service_perfdata_file_mode=a + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING INTERVAL +# These options determine how often (in seconds) the host and service +# performance data files are processed using the commands defined +# below. A value of 0 indicates the files should not be periodically +# processed. + +#host_perfdata_file_processing_interval=0 +#service_perfdata_file_processing_interval=0 + + + +# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING COMMANDS +# These commands are used to periodically process the host and +# service performance data files. The interval at which the +# processing occurs is determined by the options above. + +#host_perfdata_file_processing_command=process-host-perfdata-file +#service_perfdata_file_processing_command=process-service-perfdata-file + + + +# OBSESS OVER SERVICE CHECKS OPTION +# This determines whether or not Nagios will obsess over service +# checks and run the ocsp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over services, 0 = do not obsess (default) + +obsess_over_services=0 + + + +# OBSESSIVE COMPULSIVE SERVICE PROCESSOR COMMAND +# This is the command that is run for every service check that is +# processed by Nagios. This command is executed only if the +# obsess_over_services option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ocsp_command=somecommand + + + +# OBSESS OVER HOST CHECKS OPTION +# This determines whether or not Nagios will obsess over host +# checks and run the ochp_command defined below. Unless you're +# planning on implementing distributed monitoring, do not enable +# this option. Read the HTML docs for more information on +# implementing distributed monitoring. +# Values: 1 = obsess over hosts, 0 = do not obsess (default) + +obsess_over_hosts=0 + + + +# OBSESSIVE COMPULSIVE HOST PROCESSOR COMMAND +# This is the command that is run for every host check that is +# processed by Nagios. This command is executed only if the +# obsess_over_hosts option (above) is set to 1. The command +# argument is the short name of a command definition that you +# define in your host configuration file. Read the HTML docs for +# more information on implementing distributed monitoring. + +#ochp_command=somecommand + + + +# TRANSLATE PASSIVE HOST CHECKS OPTION +# This determines whether or not Nagios will translate +# DOWN/UNREACHABLE passive host check results into their proper +# state for this instance of Nagios. This option is useful +# if you have distributed or failover monitoring setup. In +# these cases your other Nagios servers probably have a different +# "view" of the network, with regards to the parent/child relationship +# of hosts. If a distributed monitoring server thinks a host +# is DOWN, it may actually be UNREACHABLE from the point of +# this Nagios instance. Enabling this option will tell Nagios +# to translate any DOWN or UNREACHABLE host states it receives +# passively into the correct state from the view of this server. +# Values: 1 = perform translation, 0 = do not translate (default) + +translate_passive_host_checks=0 + + + +# PASSIVE HOST CHECKS ARE SOFT OPTION +# This determines whether or not Nagios will treat passive host +# checks as being HARD or SOFT. By default, a passive host check +# result will put a host into a HARD state type. This can be changed +# by enabling this option. +# Values: 0 = passive checks are HARD, 1 = passive checks are SOFT + +passive_host_checks_are_soft=0 + + + +# ORPHANED HOST/SERVICE CHECK OPTIONS +# These options determine whether or not Nagios will periodically +# check for orphaned host service checks. Since service checks are +# not rescheduled until the results of their previous execution +# instance are processed, there exists a possibility that some +# checks may never get rescheduled. A similar situation exists for +# host checks, although the exact scheduling details differ a bit +# from service checks. Orphaned checks seem to be a rare +# problem and should not happen under normal circumstances. +# If you have problems with service checks never getting +# rescheduled, make sure you have orphaned service checks enabled. +# Values: 1 = enable checks, 0 = disable checks + +check_for_orphaned_services=1 +check_for_orphaned_hosts=1 + + + +# SERVICE FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of service results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_service_freshness=1 + + + +# SERVICE FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of service check results. If you have +# disabled service freshness checking, this option has no effect. + +service_freshness_check_interval=60 + + + +# HOST FRESHNESS CHECK OPTION +# This option determines whether or not Nagios will periodically +# check the "freshness" of host results. Enabling this option +# is useful for ensuring passive checks are received in a timely +# manner. +# Values: 1 = enabled freshness checking, 0 = disable freshness checking + +check_host_freshness=0 + + + +# HOST FRESHNESS CHECK INTERVAL +# This setting determines how often (in seconds) Nagios will +# check the "freshness" of host check results. If you have +# disabled host freshness checking, this option has no effect. + +host_freshness_check_interval=60 + + + + +# ADDITIONAL FRESHNESS THRESHOLD LATENCY +# This setting determines the number of seconds that Nagios +# will add to any host and service freshness thresholds that +# it calculates (those not explicitly specified by the user). + +additional_freshness_latency=15 + + + + +# FLAP DETECTION OPTION +# This option determines whether or not Nagios will try +# and detect hosts and services that are "flapping". +# Flapping occurs when a host or service changes between +# states too frequently. When Nagios detects that a +# host or service is flapping, it will temporarily suppress +# notifications for that host/service until it stops +# flapping. Flap detection is very experimental, so read +# the HTML documentation before enabling this feature! +# Values: 1 = enable flap detection +# 0 = disable flap detection (default) + +enable_flap_detection=1 + + + +# FLAP DETECTION THRESHOLDS FOR HOSTS AND SERVICES +# Read the HTML documentation on flap detection for +# an explanation of what this option does. This option +# has no effect if flap detection is disabled. + +low_service_flap_threshold=5.0 +high_service_flap_threshold=20.0 +low_host_flap_threshold=5.0 +high_host_flap_threshold=20.0 + + + +# DATE FORMAT OPTION +# This option determines how short dates are displayed. Valid options +# include: +# us (MM-DD-YYYY HH:MM:SS) +# euro (DD-MM-YYYY HH:MM:SS) +# iso8601 (YYYY-MM-DD HH:MM:SS) +# strict-iso8601 (YYYY-MM-DDTHH:MM:SS) +# + +date_format=iso8601 + + + + +# TIMEZONE OFFSET +# This option is used to override the default timezone that this +# instance of Nagios runs in. If not specified, Nagios will use +# the system configured timezone. +# +# NOTE: In order to display the correct timezone in the CGIs, you +# will also need to alter the Apache directives for the CGI path +# to include your timezone. Example: +# +# <Directory "/usr/local/nagios/sbin/"> +# SetEnv TZ "Australia/Brisbane" +# ... +# </Directory> + +#use_timezone=US/Mountain +#use_timezone=Australia/Brisbane + + + + +# P1.PL FILE LOCATION +# This value determines where the p1.pl perl script (used by the +# embedded Perl interpreter) is located. If you didn't compile +# Nagios with embedded Perl support, this option has no effect. + +p1_file=/usr/lib/nagios3/p1.pl + + + +# EMBEDDED PERL INTERPRETER OPTION +# This option determines whether or not the embedded Perl interpreter +# will be enabled during runtime. This option has no effect if Nagios +# has not been compiled with support for embedded Perl. +# Values: 0 = disable interpreter, 1 = enable interpreter + +enable_embedded_perl=1 + + + +# EMBEDDED PERL USAGE OPTION +# This option determines whether or not Nagios will process Perl plugins +# and scripts with the embedded Perl interpreter if the plugins/scripts +# do not explicitly indicate whether or not it is okay to do so. Read +# the HTML documentation on the embedded Perl interpreter for more +# information on how this option works. + +use_embedded_perl_implicitly=1 + + + +# ILLEGAL OBJECT NAME CHARACTERS +# This option allows you to specify illegal characters that cannot +# be used in host names, service descriptions, or names of other +# object types. + +illegal_object_name_chars=`~!$%^&*|'"<>?,()= + + + +# ILLEGAL MACRO OUTPUT CHARACTERS +# This option allows you to specify illegal characters that are +# stripped from macros before being used in notifications, event +# handlers, etc. This DOES NOT affect macros used in service or +# host check commands. +# The following macros are stripped of the characters you specify: +# $HOSTOUTPUT$ +# $HOSTPERFDATA$ +# $HOSTACKAUTHOR$ +# $HOSTACKCOMMENT$ +# $SERVICEOUTPUT$ +# $SERVICEPERFDATA$ +# $SERVICEACKAUTHOR$ +# $SERVICEACKCOMMENT$ + +illegal_macro_output_chars=`~$&|'"<> + + + +# REGULAR EXPRESSION MATCHING +# This option controls whether or not regular expression matching +# takes place in the object config files. Regular expression +# matching is used to match host, hostgroup, service, and service +# group names/descriptions in some fields of various object types. +# Values: 1 = enable regexp matching, 0 = disable regexp matching + +use_regexp_matching=0 + + + +# "TRUE" REGULAR EXPRESSION MATCHING +# This option controls whether or not "true" regular expression +# matching takes place in the object config files. This option +# only has an effect if regular expression matching is enabled +# (see above). If this option is DISABLED, regular expression +# matching only occurs if a string contains wildcard characters +# (* and ?). If the option is ENABLED, regexp matching occurs +# all the time (which can be annoying). +# Values: 1 = enable true matching, 0 = disable true matching + +use_true_regexp_matching=0 + + + +# ADMINISTRATOR EMAIL/PAGER ADDRESSES +# The email and pager address of a global administrator (likely you). +# Nagios never uses these values itself, but you can access them by +# using the $ADMINEMAIL$ and $ADMINPAGER$ macros in your notification +# commands. + +admin_email=root@localhost +admin_pager=pageroot@localhost + + + +# DAEMON CORE DUMP OPTION +# This option determines whether or not Nagios is allowed to create +# a core dump when it runs as a daemon. Note that it is generally +# considered bad form to allow this, but it may be useful for +# debugging purposes. Enabling this option doesn't guarantee that +# a core file will be produced, but that's just life... +# Values: 1 - Allow core dumps +# 0 - Do not allow core dumps (default) + +daemon_dumps_core=0 + + + +# LARGE INSTALLATION TWEAKS OPTION +# This option determines whether or not Nagios will take some shortcuts +# which can save on memory and CPU usage in large Nagios installations. +# Read the documentation for more information on the benefits/tradeoffs +# of enabling this option. +# Values: 1 - Enabled tweaks +# 0 - Disable tweaks (default) + +use_large_installation_tweaks=0 + + + +# ENABLE ENVIRONMENT MACROS +# This option determines whether or not Nagios will make all standard +# macros available as environment variables when host/service checks +# and system commands (event handlers, notifications, etc.) are +# executed. Enabling this option can cause performance issues in +# large installations, as it will consume a bit more memory and (more +# importantly) consume more CPU. +# Values: 1 - Enable environment variable macros (default) +# 0 - Disable environment variable macros + +enable_environment_macros=1 + + + +# CHILD PROCESS MEMORY OPTION +# This option determines whether or not Nagios will free memory in +# child processes (processed used to execute system commands and host/ +# service checks). If you specify a value here, it will override +# program defaults. +# Value: 1 - Free memory in child processes +# 0 - Do not free memory in child processes + +#free_child_process_memory=1 + + + +# CHILD PROCESS FORKING BEHAVIOR +# This option determines how Nagios will fork child processes +# (used to execute system commands and host/service checks). Normally +# child processes are fork()ed twice, which provides a very high level +# of isolation from problems. Fork()ing once is probably enough and will +# save a great deal on CPU usage (in large installs), so you might +# want to consider using this. If you specify a value here, it will +# program defaults. +# Value: 1 - Child processes fork() twice +# 0 - Child processes fork() just once + +#child_processes_fork_twice=1 + + + +# DEBUG LEVEL +# This option determines how much (if any) debugging information will +# be written to the debug file. OR values together to log multiple +# types of information. +# Values: +# -1 = Everything +# 0 = Nothing +# 1 = Functions +# 2 = Configuration +# 4 = Process information +# 8 = Scheduled events +# 16 = Host/service checks +# 32 = Notifications +# 64 = Event broker +# 128 = External commands +# 256 = Commands +# 512 = Scheduled downtime +# 1024 = Comments +# 2048 = Macros + +debug_level=0 + + + +# DEBUG VERBOSITY +# This option determines how verbose the debug log out will be. +# Values: 0 = Brief output +# 1 = More detailed +# 2 = Very detailed + +debug_verbosity=1 + + + +# DEBUG FILE +# This option determines where Nagios should write debugging information. + +debug_file=/var/lib/nagios3/nagios.debug + + + +# MAX DEBUG FILE SIZE +# This option determines the maximum size (in bytes) of the debug file. If +# the file grows larger than this size, it will be renamed with a .old +# extension. If a file already exists with a .old extension it will +# automatically be deleted. This helps ensure your disk space usage doesn't +# get out of control when debugging Nagios. + +max_debug_file_size=1000000 + + diff --git a/puppet/modules/nagios/files/configs/Debian/private/resource.cfg.amd64 b/puppet/modules/nagios/files/configs/Debian/private/resource.cfg.amd64 new file mode 100644 index 00000000..3ed732bb --- /dev/null +++ b/puppet/modules/nagios/files/configs/Debian/private/resource.cfg.amd64 @@ -0,0 +1,31 @@ +########################################################################### +# +# RESOURCE.CFG - Resource File for Nagios +# +# You can define $USERx$ macros in this file, which can in turn be used +# in command definitions in your host config file(s). $USERx$ macros are +# useful for storing sensitive information such as usernames, passwords, +# etc. They are also handy for specifying the path to plugins and +# event handlers - if you decide to move the plugins or event handlers to +# a different directory in the future, you can just update one or two +# $USERx$ macros, instead of modifying a lot of command definitions. +# +# The CGIs will not attempt to read the contents of resource files, so +# you can set restrictive permissions (600 or 660) on them. +# +# Nagios supports up to 32 $USERx$ macros ($USER1$ through $USER32$) +# +# Resource files may also be used to store configuration directives for +# external data sources like MySQL... +# +########################################################################### + +# Sets $USER1$ to be the path to the plugins +$USER1$=/usr/lib/nagios/plugins + +# Sets $USER2$ to be the path to event handlers +#$USER2$=/usr/lib/nagios/plugins/eventhandlers + +# Store some usernames and passwords (hidden from the CGIs) +#$USER3$=someuser +#$USER4$=somepassword diff --git a/puppet/modules/nagios/files/configs/Debian/private/resource.cfg.i386 b/puppet/modules/nagios/files/configs/Debian/private/resource.cfg.i386 new file mode 100644 index 00000000..3ed732bb --- /dev/null +++ b/puppet/modules/nagios/files/configs/Debian/private/resource.cfg.i386 @@ -0,0 +1,31 @@ +########################################################################### +# +# RESOURCE.CFG - Resource File for Nagios +# +# You can define $USERx$ macros in this file, which can in turn be used +# in command definitions in your host config file(s). $USERx$ macros are +# useful for storing sensitive information such as usernames, passwords, +# etc. They are also handy for specifying the path to plugins and +# event handlers - if you decide to move the plugins or event handlers to +# a different directory in the future, you can just update one or two +# $USERx$ macros, instead of modifying a lot of command definitions. +# +# The CGIs will not attempt to read the contents of resource files, so +# you can set restrictive permissions (600 or 660) on them. +# +# Nagios supports up to 32 $USERx$ macros ($USER1$ through $USER32$) +# +# Resource files may also be used to store configuration directives for +# external data sources like MySQL... +# +########################################################################### + +# Sets $USER1$ to be the path to the plugins +$USER1$=/usr/lib/nagios/plugins + +# Sets $USER2$ to be the path to event handlers +#$USER2$=/usr/lib/nagios/plugins/eventhandlers + +# Store some usernames and passwords (hidden from the CGIs) +#$USER3$=someuser +#$USER4$=somepassword diff --git a/puppet/modules/nagios/files/configs/Debian/private/resource.cfg.x86_64 b/puppet/modules/nagios/files/configs/Debian/private/resource.cfg.x86_64 new file mode 100644 index 00000000..3ed732bb --- /dev/null +++ b/puppet/modules/nagios/files/configs/Debian/private/resource.cfg.x86_64 @@ -0,0 +1,31 @@ +########################################################################### +# +# RESOURCE.CFG - Resource File for Nagios +# +# You can define $USERx$ macros in this file, which can in turn be used +# in command definitions in your host config file(s). $USERx$ macros are +# useful for storing sensitive information such as usernames, passwords, +# etc. They are also handy for specifying the path to plugins and +# event handlers - if you decide to move the plugins or event handlers to +# a different directory in the future, you can just update one or two +# $USERx$ macros, instead of modifying a lot of command definitions. +# +# The CGIs will not attempt to read the contents of resource files, so +# you can set restrictive permissions (600 or 660) on them. +# +# Nagios supports up to 32 $USERx$ macros ($USER1$ through $USER32$) +# +# Resource files may also be used to store configuration directives for +# external data sources like MySQL... +# +########################################################################### + +# Sets $USER1$ to be the path to the plugins +$USER1$=/usr/lib/nagios/plugins + +# Sets $USER2$ to be the path to event handlers +#$USER2$=/usr/lib/nagios/plugins/eventhandlers + +# Store some usernames and passwords (hidden from the CGIs) +#$USER3$=someuser +#$USER4$=somepassword diff --git a/puppet/modules/nagios/files/configs/apache2.conf b/puppet/modules/nagios/files/configs/apache2.conf new file mode 100644 index 00000000..f0f8b2f3 --- /dev/null +++ b/puppet/modules/nagios/files/configs/apache2.conf @@ -0,0 +1,67 @@ +# apache configuration for nagios 3.x +# note to users of nagios 1.x and 2.x: +# throughout this file are commented out sections which preserve +# backwards compatibility with bookmarks/config for older nagios versios. +# simply look for lines following "nagios 1.x:" and "nagios 2.x" comments. + +ScriptAlias /cgi-bin/nagios3 /usr/lib/cgi-bin/nagios3 +ScriptAlias /nagios3/cgi-bin /usr/lib/cgi-bin/nagios3 +# nagios 1.x: +#ScriptAlias /cgi-bin/nagios /usr/lib/cgi-bin/nagios3 +#ScriptAlias /nagios/cgi-bin /usr/lib/cgi-bin/nagios3 +# nagios 2.x: +#ScriptAlias /cgi-bin/nagios2 /usr/lib/cgi-bin/nagios3 +#ScriptAlias /nagios2/cgi-bin /usr/lib/cgi-bin/nagios3 + +# Where the stylesheets (config files) reside +Alias /nagios3/stylesheets /etc/nagios3/stylesheets +# nagios 1.x: +#Alias /nagios/stylesheets /etc/nagios3/stylesheets +# nagios 2.x: +#Alias /nagios2/stylesheets /etc/nagios3/stylesheets + +# Where the HTML pages live +Alias /nagios3 /usr/share/nagios3/htdocs +# nagios 2.x: +#Alias /nagios2 /usr/share/nagios3/htdocs +# nagios 1.x: +#Alias /nagios /usr/share/nagios3/htdocs + +<DirectoryMatch (/usr/share/nagios3/htdocs|/usr/lib/cgi-bin/nagios3|/etc/nagios3/stylesheets)> + Options FollowSymLinks + + DirectoryIndex index.php index.html + + AllowOverride AuthConfig + + + <IfVersion < 2.3> + Order Allow,Deny + Allow From All + </IfVersion> + + <IfVersion >= 2.3> + Require all denied + </IfVersion> + + AuthName "Nagios Access" + AuthType Basic + AuthUserFile /etc/nagios3/htpasswd.users + # nagios 1.x: + #AuthUserFile /etc/nagios/htpasswd.users + require valid-user +</DirectoryMatch> + +<Directory /usr/share/nagios3/htdocs> + Options +ExecCGI +</Directory> + +# Enable this ScriptAlias if you want to enable the grouplist patch. +# See http://apan.sourceforge.net/download.html for more info +# It allows you to see a clickable list of all hostgroups in the +# left pane of the Nagios web interface +# XXX This is not tested for nagios 2.x use at your own peril +#ScriptAlias /nagios3/side.html /usr/lib/cgi-bin/nagios3/grouplist.cgi +# nagios 1.x: +#ScriptAlias /nagios/side.html /usr/lib/cgi-bin/nagios3/grouplist.cgi + diff --git a/puppet/modules/nagios/files/configs/cgi.cfg b/puppet/modules/nagios/files/configs/cgi.cfg new file mode 120000 index 00000000..db9667b3 --- /dev/null +++ b/puppet/modules/nagios/files/configs/cgi.cfg @@ -0,0 +1 @@ +Debian/cgi.cfg
\ No newline at end of file diff --git a/puppet/modules/nagios/files/configs/nagios.cfg b/puppet/modules/nagios/files/configs/nagios.cfg new file mode 120000 index 00000000..1409b9e8 --- /dev/null +++ b/puppet/modules/nagios/files/configs/nagios.cfg @@ -0,0 +1 @@ +Debian/nagios.cfg
\ No newline at end of file diff --git a/puppet/modules/nagios/files/configs/nagios_templates.cfg b/puppet/modules/nagios/files/configs/nagios_templates.cfg new file mode 100644 index 00000000..98596713 --- /dev/null +++ b/puppet/modules/nagios/files/configs/nagios_templates.cfg @@ -0,0 +1,49 @@ +define host{ + name generic-host ; The name of this host template + notifications_enabled 1 ; Host notifications are enabled + event_handler_enabled 1 ; Host event handler is enabled + flap_detection_enabled 1 ; Flap detection is enabled + failure_prediction_enabled 1 ; Failure prediction is enabled + process_perf_data 1 ; Process performance data + retain_status_information 1 ; Retain status information across program restarts + retain_nonstatus_information 1 ; Retain non-status information across program restarts + check_command check-host-alive + max_check_attempts 10 + notification_interval 0 + notification_period 24x7 + notification_options d,u,r + contact_groups admins + register 0 ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL HOST, JUST A TEMPLATE! +} + +define service{ + name generic-service ; The 'name' of this service template + active_checks_enabled 1 ; Active service checks are enabled + passive_checks_enabled 1 ; Passive service checks are enabled/accepted + parallelize_check 1 ; Active service checks should be parallelized (disabling this can lead to major performance problems) + obsess_over_service 1 ; We should obsess over this service (if necessary) + check_freshness 0 ; Default is to NOT check service 'freshness' + notifications_enabled 1 ; Service notifications are enabled + event_handler_enabled 1 ; Service event handler is enabled + flap_detection_enabled 1 ; Flap detection is enabled + failure_prediction_enabled 1 ; Failure prediction is enabled + process_perf_data 1 ; Process performance data + retain_status_information 1 ; Retain status information across program restarts + retain_nonstatus_information 1 ; Retain non-status information across program restarts + notification_interval 0 ; Only send notifications on status change by default. + is_volatile 0 + check_period 24x7 + normal_check_interval 5 + retry_check_interval 1 + max_check_attempts 4 + notification_period 24x7 + notification_options w,u,c,r + contact_groups admins + register 0 ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL SERVICE, JUST A TEMPLATE! +} + +define service{ + name passive-service + use generic-service + active_checks_enabled 0 +} diff --git a/puppet/modules/nagios/files/htpasswd.users b/puppet/modules/nagios/files/htpasswd.users new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/puppet/modules/nagios/files/htpasswd.users diff --git a/puppet/modules/nagios/files/irc_bot/riseup-nagios-client.pl b/puppet/modules/nagios/files/irc_bot/riseup-nagios-client.pl new file mode 100644 index 00000000..2467058d --- /dev/null +++ b/puppet/modules/nagios/files/irc_bot/riseup-nagios-client.pl @@ -0,0 +1,72 @@ +#!/usr/bin/perl -w + +# ############################################################################## +# Infrabot-Client - a simple Infrabot client which sends it's whole command +# line arguments to a local UNIX domain socket. +# ############################################################################## + +use strict; +use IO::Socket; + + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# >> CONFIGURATION >> + +# Read a configuration file +# The arg can be a relative or full path, or +# it can be a file located somewhere in @INC. +sub ReadCfg +{ + my $file = $_[0]; + + our $err; + + { # Put config data into a separate namespace + package CFG; + + # Process the contents of the config file + my $rc = do($file); + + # Check for errors + if ($@) { + $::err = "ERROR: Failure compiling '$file' - $@"; + } elsif (! defined($rc)) { + $::err = "ERROR: Failure reading '$file' - $!"; + } elsif (! $rc) { + $::err = "ERROR: Failure processing '$file'"; + } + } + + return ($err); +} + +# Get our configuration information +if (my $err = ReadCfg('/etc/nagios_nsa.cfg')) { + print(STDERR $err, "\n"); + exit(1); +} + +# << CONFIGURATION << +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +if (@ARGV == 0) { + print "Hey - specify a message, sucker!\n"; + exit(1); +} + +unless (-S $CFG::Nsa{'socket'}) { + die "Socket '$CFG::Nsa{'socket'}' doesn't exist or isn't a socket!\n"; +} + +unless (-r $CFG::Nsa{'socket'}) { + die "Socket '$CFG::Nsa{'socket'}' can't be read!\n"; +} + +my $sock = IO::Socket::UNIX->new ( + Peer => $CFG::Nsa{'socket'}, + Type => SOCK_DGRAM, + Timeout => 10 +) || die "Can't open socket '$CFG::Nsa{'socket'}'!\n"; + +print $sock "@ARGV"; +close($sock); diff --git a/puppet/modules/nagios/files/irc_bot/riseup-nagios-server.pl b/puppet/modules/nagios/files/irc_bot/riseup-nagios-server.pl new file mode 100644 index 00000000..5d65e6dd --- /dev/null +++ b/puppet/modules/nagios/files/irc_bot/riseup-nagios-server.pl @@ -0,0 +1,239 @@ +#!/usr/bin/perl -w + +# ############################################################################## +# a simple IRC bot which dispatches messages received via local domain sockets +# ############################################################################## + + +###### +## THIS NEEDS TO BE PORTED TO THE NEW FRAMEWORKS! +## +## STICKY POINTS: the addfh() function doesn't exist in BasicBot or POE::Component::IRC +## +## people suggested we use Anyevent::IRC and POE::Kernel ->select_read and POE::Wheel namespace +## +## in the meantime, inspiration for extensions can be found here: http://svn.foswiki.org/trunk/WikiBot/mozbot.pl + +use strict; +use File::Basename; + +BEGIN { + unshift @INC, dirname($0); +} + +my $VERSION = '0.2'; +my $running = 1; + +# Read a configuration file +# The arg can be a relative or full path, or +# it can be a file located somewhere in @INC. +sub ReadCfg +{ + my $file = $_[0]; + + our $err; + + { # Put config data into a separate namespace + package CFG; + + # Process the contents of the config file + my $rc = do($file); + + # Check for errors + if ($@) { + $::err = "ERROR: Failure compiling '$file' - $@"; + } elsif (! defined($rc)) { + $::err = "ERROR: Failure reading '$file' - $!"; + } elsif (! $rc) { + $::err = "ERROR: Failure processing '$file'"; + } + } + + return ($err); +} + +# Get our configuration information +if (my $err = ReadCfg('/etc/nagios_nsa.cfg')) { + print(STDERR $err, "\n"); + exit(1); +} + +use POSIX qw(setsid); +use IO::Socket; +use Net::IRC; + +sub new { + my $self = { + socket => undef, + irc => undef, + conn => undef, + commandfile => undef, + }; + + return bless($self, __PACKAGE__); +} + +sub daemonize { + my $self = shift; + my $pid; + + chdir '/' or die "Can't chdir to /: $!"; + + open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; + open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!"; + + defined ($pid = fork) or die "Can't fork: $!"; + + if ($pid && $CFG::Nsa{'pidfile'}) { # write pid of child + open PID, ">$CFG::Nsa{'pidfile'}" or die "Can't open pid file: $!"; + print PID $pid; + close PID; + } + exit if $pid; + setsid or die "Can't start a new session: $!"; + + #open STDERR, '>&STDOUT' or die "Can't dup stdout: $!"; +} + +sub run { + my $self = shift; + + $self->{irc}->do_one_loop(); +} + +sub shutdown { + my $sig = shift; + + print STDERR "Received SIG$sig, shutting down...\n"; + $running = 0; +} + +sub socket_has_data { + my $self = shift; + + $self->{socket}->recv(my $data, 1024); + if ($CFG::Nsa{'usenotices'}) { + $self->{conn}->notice($CFG::Nsa{'channel'}, $data); + } else { + $self->{conn}->privmsg($CFG::Nsa{'channel'}, $data); + } +} + +sub irc_on_connect { + my $self = shift; + + print STDERR "Joining channel '$CFG::Nsa{'channel'}'...\n"; + $self->join($CFG::Nsa{'channel'}); +} + +sub irc_on_msg { + my ($self, $event) = @_; + my $data = join(' ', $event->args); + #my $nick = quotemeta($nicks[$nick]); + my $to = $event->to; + #my $channel = &toToChannel($self, @$to); + #my $cmdChar = $commandChar{default}; # FIXME: should look up for CURRENT channel first! + #if ( exists $commandChar{$channel} ) { $cmdChar = $commandChar{$channel}; } + my $msg = parse_msg($event); + if (defined($msg)) { + #$self->privmsg($event->nick, "alright, sending this message to nagios, hope it figures it out: $msg"); + } else { + $self->privmsg($event->nick, "can't parse $data, you want 'ack host service comment'\n"); + } +} + +sub irc_on_public { + my ($self, $event) = @_; + my $data = join(' ', $event->args); + my $to = $event->to; + if ($data =~ s/([^:]*):\s+//) { + if ($1 eq $CFG::Nsa{'nickname'}) { + my $msg = parse_msg($event); + if (defined($msg)) { + #$self->privmsg($event->to, "alright, sending this message to nagios, hope it figures it out: $msg"); + } else { + $self->privmsg($event->to, "can't parse $data, you want 'ack host service comment'\n"); + } + } else { + #print STDERR "ignoring message $data, not for me (me being $1)\n"; + } + } else { + #print STDERR "ignoring message $data\n"; + } +} + +sub parse_msg { + my $event= shift; + my $data = join(' ', $event->args); + my $msg; + if ($data =~ m/([^:]*:)?\s*ack(?:knowledge)?\s+([a-zA-Z0-9\-\.]+)(?:\s+([-\w\.]+)(?:\s+([\w\s]+))?)?/) { + #print STDERR "writing to nagios scoket ". $CFG::Nsa{'commandfile'} . "\n"; + open(my $cmdfile, ">", $CFG::Nsa{'commandfile'}) || die "Can't open Nagios commandfile: $CFG::Nsa{'commandfile'}!\n"; + my $host = $2; + my ($service, $comment) = (undef, "no comment (from irc)"); + if ($4) { + $service = $3; + $comment = $4; + } elsif ($3) { + $service = $3; + } + my $user = $event->nick; + $msg = '[' . time() . '] '; + if (defined($service)) { + $msg .= "ACKNOWLEDGE_SVC_PROBLEM;$host;$service;1;1;1;$user;$comment\n"; + } else { + $msg .= "ACKNOWLEDGE_HOST_PROBLEM;$host;1;1;1;$user;$comment\n"; + } + print {$cmdfile} $msg; + close($cmdfile); + } + return $msg; +} + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +my $bot = &new; + +if (-e $CFG::Nsa{'socket'}) { + die "Socket '$CFG::Nsa{'socket'}' exists!\n"; +} + +$bot->{socket} = IO::Socket::UNIX->new ( + Local => $CFG::Nsa{'socket'}, + Type => SOCK_DGRAM, + Listen => 5 +) || die "Can't create socket '$CFG::Nsa{'socket'}'!\n"; + +$SIG{INT} = $SIG{TERM} = \&shutdown; + +$bot->daemonize(); +$bot->{irc} = new Net::IRC; + +$bot->{conn} = $bot->{irc}->newconn ( + Server => $CFG::Nsa{'server'}, + Port => $CFG::Nsa{'port'}, + Nick => $CFG::Nsa{'nickname'}, + Username => $CFG::Nsa{'nickname'}, + Password => $CFG::Nsa{'password'}, + Ircname => $CFG::Nsa{'realname'} . " (NSA $VERSION)", +) || die "Can't connect to server '$CFG::Nsa{'server'}'!\n"; + +$bot->{conn}->add_global_handler(376, \&irc_on_connect); +$bot->{conn}->add_global_handler('nomotd', \&irc_on_connect); +$bot->{conn}->add_global_handler('msg', \&irc_on_msg); +$bot->{conn}->add_global_handler('public', \&irc_on_public); +#$bot->{conn}->add_global_handler('notice', \&irc_on_msg); +$bot->{irc}->addfh($bot->{socket}, \&socket_has_data, 'r', $bot); + +while ($running) { + $bot->run(); +} + +close($bot->{socket}); +unlink($CFG::Nsa{'socket'}); + +exit(0); + +1; + +__END__ diff --git a/puppet/modules/nagios/files/munin/nagios_hosts b/puppet/modules/nagios/files/munin/nagios_hosts new file mode 100644 index 00000000..3fa00f1d --- /dev/null +++ b/puppet/modules/nagios/files/munin/nagios_hosts @@ -0,0 +1,32 @@ +#!/bin/bash + +if [ -z "$nag_stats_binary" ]; then + nag_stats_binary=/usr/sbin/nagios3stats +fi + +if [ "$1" = "config" ]; then + echo 'graph_title Nagios host stats' + echo 'graph_args --base 1000 -l 0' + echo 'graph_vlabel hosts' + echo 'graph_category nagios' + echo 'graph_info The number of hosts checked by nagios' + echo 'up.label up' + echo 'up.draw AREA' + echo 'up.info number of hosts UP' + echo 'down.label down' + echo 'down.draw STACK' + echo 'down.info number of hosts DOWN' + echo 'unr.label unr' + echo 'unr.draw STACK' + echo 'unr.info number of hosts UNREACHABLE' + + exit 0 +fi + +echo -n 'up.value ' +$nag_stats_binary --mrtg --data NUMHSTUP +echo -n 'down.value ' +$nag_stats_binary --mrtg --data NUMHSTDOWN +echo -n 'unr.value ' +$nag_stats_binary --mrtg --data NUMHSTUNR + diff --git a/puppet/modules/nagios/files/munin/nagios_perf b/puppet/modules/nagios/files/munin/nagios_perf new file mode 100644 index 00000000..609d62f4 --- /dev/null +++ b/puppet/modules/nagios/files/munin/nagios_perf @@ -0,0 +1,38 @@ +#!/bin/bash + +if [ -z "$nag_stats_binary" ]; then + nag_stats_binary=/usr/sbin/nagios3stats +fi + +NAME=$(basename $0) + +TYPE=${NAME##nagios_perf_} + +[ "x$TYPE" = 'xhosts' ] && TYPE_ABBR=HST +[ "x$TYPE" = 'xsvc' ] && TYPE_ABBR=SVC +[ -z "$TYPE_ABBR" ] && echo "unknown type $TYPE" >&2 && exit 1 + +if [ "$1" = "config" ]; then + echo "graph_title Nagios $TYPE performance stats" + echo "graph_args --base 1000" + echo "graph_vlabel seconds" + echo "graph_category nagios" + echo "graph_info Check performance statistics" + + echo "act_lat_$TYPE_ABBR.label act lat" + echo "act_lat_$TYPE_ABBR.type GAUGE" + echo "act_lat_$TYPE_ABBR.draw AREA" + echo "act_lat_$TYPE_ABBR.cdef act_lat_$TYPE_ABBR,1000,/" + echo "act_lat_$TYPE_ABBR.info average latency of active checks over the last 5 minutes" + + echo "act_ext_$TYPE_ABBR.label act ext" + echo "act_ext_$TYPE_ABBR.type GAUGE" + echo "act_ext_$TYPE_ABBR.draw LINE1" + echo "act_ext_$TYPE_ABBR.cdef act_ext_$TYPE_ABBR,1000,/" + echo "act_ext_$TYPE_ABBR.info average execution time of active checks over the last 5 minutes" + + exit 0 +fi + +echo "act_lat_$TYPE_ABBR.value " $($nag_stats_binary --mrtg --data AVGACT${TYPE_ABBR}LAT) +echo "act_ext_$TYPE_ABBR.value " $($nag_stats_binary --mrtg --data AVGACT${TYPE_ABBR}EXT) diff --git a/puppet/modules/nagios/files/munin/nagios_svc b/puppet/modules/nagios/files/munin/nagios_svc new file mode 100644 index 00000000..97c8bfc1 --- /dev/null +++ b/puppet/modules/nagios/files/munin/nagios_svc @@ -0,0 +1,37 @@ +#!/bin/bash + +if [ -z "$nag_stats_binary" ]; then + nag_stats_binary=/usr/sbin/nagios3stats +fi + +if [ "$1" = "config" ]; then + echo 'graph_title Nagios service stats' + echo 'graph_args --base 1000 -l 0' + echo 'graph_vlabel services' + echo 'graph_category nagios' + echo 'graph_info The number of services checked by nagios' + echo 'ok.label ok' + echo 'ok.draw AREA' + echo 'ok.info number of services OK' + echo 'warn.label warn' + echo 'warn.draw STACK' + echo 'warn.info number of services WARNING' + echo 'crit.label crit' + echo 'crit.draw STACK' + echo 'crit.info number of services CRITICAL' + echo 'unkn.label unkn' + echo 'unkn.draw STACK' + echo 'unkn.info number of services UNKNOWN' + + exit 0 +fi + +echo -n 'ok.value ' +$nag_stats_binary --mrtg --data NUMSVCOK +echo -n 'warn.value ' +$nag_stats_binary --mrtg --data NUMSVCWARN +echo -n 'crit.value ' +$nag_stats_binary --mrtg --data NUMSVCCRIT +echo -n 'unkn.value ' +$nag_stats_binary --mrtg --data NUMSVCUNKN + diff --git a/puppet/modules/nagios/files/nrpe/nrpe_commands.cfg b/puppet/modules/nagios/files/nrpe/nrpe_commands.cfg new file mode 100644 index 00000000..b725a36a --- /dev/null +++ b/puppet/modules/nagios/files/nrpe/nrpe_commands.cfg @@ -0,0 +1,5 @@ +# default plugins +command[check_users]=/usr/lib/nagios/plugins/check_users $ARG1$ +command[check_disk]=/usr/lib/nagios/plugins/check_disk $ARG1$ -x "/dev" -x "/dev/shm" -x "/lib/init/rw" +command[check_apt]=sudo /usr/lib/nagios/plugins/check_apt -u $ARG1$ +command[check_swap]=/usr/lib/nagios/plugins/check_swap $ARG1$ diff --git a/puppet/modules/nagios/files/nsca/nsca.cfg b/puppet/modules/nagios/files/nsca/nsca.cfg new file mode 100644 index 00000000..0b019ea1 --- /dev/null +++ b/puppet/modules/nagios/files/nsca/nsca.cfg @@ -0,0 +1,197 @@ +# This file is managed by Puppet. +# +#################################################### +# Sample NSCA Daemon Config File +# Written by: Ethan Galstad (nagios@nagios.org) +# +# Last Modified: 04-03-2006 +#################################################### + + +# PID FILE +# The name of the file in which the NSCA daemon should write it's process ID +# number. The file is only written if the NSCA daemon is started by the root +# user as a single- or multi-process daemon. + +pid_file=/var/run/nsca.pid + + + +# PORT NUMBER +# Port number we should wait for connections on. +# This must be a non-priveledged port (i.e. > 1024). + +server_port=5667 + + + +# SERVER ADDRESS +# Address that NSCA has to bind to in case there are +# more as one interface and we do not want NSCA to bind +# (thus listen) on all interfaces. + +#server_address=192.168.1.1 + + + +# NSCA USER +# This determines the effective user that the NSCA daemon should run as. +# You can either supply a username or a UID. +# +# NOTE: This option is ignored if NSCA is running under either inetd or xinetd + +nsca_user=nagios + + + +# NSCA GROUP +# This determines the effective group that the NSCA daemon should run as. +# You can either supply a group name or a GID. +# +# NOTE: This option is ignored if NSCA is running under either inetd or xinetd + +nsca_group=nogroup + + + +# NSCA CHROOT +# If specified, determines a directory into which the nsca daemon +# will perform a chroot(2) operation before dropping its privileges. +# for the security conscious this can add a layer of protection in +# the event that the nagios daemon is compromised. +# +# NOTE: if you specify this option, the command file will be opened +# relative to this directory. + +#nsca_chroot=/var/run/nagios/rw + + + +# DEBUGGING OPTION +# This option determines whether or not debugging +# messages are logged to the syslog facility. +# Values: 0 = debugging off, 1 = debugging on + +debug=0 + + + +# COMMAND FILE +# This is the location of the Nagios command file that the daemon +# should write all service check results that it receives. +# Note to debian users: nagios 1.x and nagios 2.x have +# different default locations for this file. this is the +# default location for nagios 1.x: +#command_file=/var/run/nagios/nagios.cmd +# and this is the default location for nagios2: +#command_file=/var/lib/nagios2/rw/nagios.cmd +# and this is the default location for nagios3: +command_file=/var/lib/nagios3/rw/nagios.cmd + +# ALTERNATE DUMP FILE +# This is used to specify an alternate file the daemon should +# write service check results to in the event the command file +# does not exist. It is important to note that the command file +# is implemented as a named pipe and only exists when Nagios is +# running. You may want to modify the startup script for Nagios +# to dump the contents of this file into the command file after +# it starts Nagios. Or you may simply choose to ignore any +# check results received while Nagios was not running... + +alternate_dump_file=/var/run/nagios/nsca.dump + + +# AGGREGATED WRITES OPTION +# This option determines whether or not the nsca daemon will +# aggregate writes to the external command file for client +# connections that contain multiple check results. If you +# are queueing service check results on remote hosts and +# sending them to the nsca daemon in bulk, you will probably +# want to enable bulk writes, as this will be a bit more +# efficient. +# Values: 0 = do not aggregate writes, 1 = aggregate writes + +aggregate_writes=0 + + + +# APPEND TO FILE OPTION +# This option determines whether or not the nsca daemon will +# will open the external command file for writing or appending. +# This option should almost *always* be set to 0! +# Values: 0 = open file for writing, 1 = open file for appending + +append_to_file=0 + + + +# MAX PACKET AGE OPTION +# This option is used by the nsca daemon to determine when client +# data is too old to be valid. Keeping this value as small as +# possible is recommended, as it helps prevent the possibility of +# "replay" attacks. This value needs to be at least as long as +# the time it takes your clients to send their data to the server. +# Values are in seconds. The max packet age cannot exceed 15 +# minutes (900 seconds). If this variable is set to zero (0), no +# packets will be rejected based on their age. + +max_packet_age=30 + + + +# DECRYPTION PASSWORD +# This is the password/passphrase that should be used to descrypt the +# incoming packets. Note that all clients must encrypt the packets +# they send using the same password! +# IMPORTANT: You don't want all the users on this system to be able +# to read the password you specify here, so make sure to set +# restrictive permissions on this config file! + +#password= + + + +# DECRYPTION METHOD +# This option determines the method by which the nsca daemon will +# decrypt the packets it receives from the clients. The decryption +# method you choose will be a balance between security and performance, +# as strong encryption methods consume more processor resources. +# You should evaluate your security needs when choosing a decryption +# method. +# +# Note: The decryption method you specify here must match the +# encryption method the nsca clients use (as specified in +# the send_nsca.cfg file)!! +# Values: +# +# 0 = None (Do NOT use this option) +# 1 = Simple XOR (No security, just obfuscation, but very fast) +# +# 2 = DES +# 3 = 3DES (Triple DES) +# 4 = CAST-128 +# 5 = CAST-256 +# 6 = xTEA +# 7 = 3WAY +# 8 = BLOWFISH +# 9 = TWOFISH +# 10 = LOKI97 +# 11 = RC2 +# 12 = ARCFOUR +# +# 14 = RIJNDAEL-128 +# 15 = RIJNDAEL-192 +# 16 = RIJNDAEL-256 +# +# 19 = WAKE +# 20 = SERPENT +# +# 22 = ENIGMA (Unix crypt) +# 23 = GOST +# 24 = SAFER64 +# 25 = SAFER128 +# 26 = SAFER+ +# + +decryption_method=1 + diff --git a/puppet/modules/nagios/files/nsca/send_nsca.cfg b/puppet/modules/nagios/files/nsca/send_nsca.cfg new file mode 100644 index 00000000..8127226b --- /dev/null +++ b/puppet/modules/nagios/files/nsca/send_nsca.cfg @@ -0,0 +1,65 @@ +# This file is managed by Puppet. +# +#################################################### +# Sample NSCA Client Config File +# Written by: Ethan Galstad (nagios@nagios.org) +# +# Last Modified: 02-21-2002 +#################################################### + + +# ENCRYPTION PASSWORD +# This is the password/passphrase that should be used to encrypt the +# outgoing packets. Note that the nsca daemon must use the same +# password when decrypting the packet! +# IMPORTANT: You don't want all the users on this system to be able +# to read the password you specify here, so make sure to set +# restrictive permissions on this config file! + +#password= + + + +# ENCRYPTION METHOD +# This option determines the method by which the send_nsca client will +# encrypt the packets it sends to the nsca daemon. The encryption +# method you choose will be a balance between security and performance, +# as strong encryption methods consume more processor resources. +# You should evaluate your security needs when choosing an encryption +# method. +# +# Note: The encryption method you specify here must match the +# decryption method the nsca daemon uses (as specified in +# the nsca.cfg file)!! +# Values: +# 0 = None (Do NOT use this option) +# 1 = Simple XOR (No security, just obfuscation, but very fast) +# +# 2 = DES +# 3 = 3DES (Triple DES) +# 4 = CAST-128 +# 5 = CAST-256 +# 6 = xTEA +# 7 = 3WAY +# 8 = BLOWFISH +# 9 = TWOFISH +# 10 = LOKI97 +# 11 = RC2 +# 12 = ARCFOUR +# +# 14 = RIJNDAEL-128 +# 15 = RIJNDAEL-192 +# 16 = RIJNDAEL-256 +# +# 19 = WAKE +# 20 = SERPENT +# +# 22 = ENIGMA (Unix crypt) +# 23 = GOST +# 24 = SAFER64 +# 25 = SAFER128 +# 26 = SAFER+ +# + +encryption_method=1 + diff --git a/puppet/modules/nagios/files/plugin_data/sks-keyservers.netCA.pem b/puppet/modules/nagios/files/plugin_data/sks-keyservers.netCA.pem new file mode 100644 index 00000000..24a2ad2e --- /dev/null +++ b/puppet/modules/nagios/files/plugin_data/sks-keyservers.netCA.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFizCCA3OgAwIBAgIJAK9zyLTPn4CPMA0GCSqGSIb3DQEBBQUAMFwxCzAJBgNV +BAYTAk5PMQ0wCwYDVQQIDARPc2xvMR4wHAYDVQQKDBVza3Mta2V5c2VydmVycy5u +ZXQgQ0ExHjAcBgNVBAMMFXNrcy1rZXlzZXJ2ZXJzLm5ldCBDQTAeFw0xMjEwMDkw +MDMzMzdaFw0yMjEwMDcwMDMzMzdaMFwxCzAJBgNVBAYTAk5PMQ0wCwYDVQQIDARP +c2xvMR4wHAYDVQQKDBVza3Mta2V5c2VydmVycy5uZXQgQ0ExHjAcBgNVBAMMFXNr +cy1rZXlzZXJ2ZXJzLm5ldCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBANdsWy4PXWNUCkS3L//nrd0GqN3dVwoBGZ6w94Tw2jPDPifegwxQozFXkG6I +6A4TK1CJLXPvfz0UP0aBYyPmTNadDinaB9T4jIwd4rnxl+59GiEmqkN3IfPsv5Jj +MkKUmJnvOT0DEVlEaO1UZIwx5WpfprB3mR81/qm4XkAgmYrmgnLXd/pJDAMk7y1F +45b5zWofiD5l677lplcIPRbFhpJ6kDTODXh/XEdtF71EAeaOdEGOvyGDmCO0GWqS +FDkMMPTlieLA/0rgFTcz4xwUYj/cD5e0ZBuSkYsYFAU3hd1cGfBue0cPZaQH2HYx +Qk4zXD8S3F4690fRhr+tki5gyG6JDR67aKp3BIGLqm7f45WkX1hYp+YXywmEziM4 +aSbGYhx8hoFGfq9UcfPEvp2aoc8u5sdqjDslhyUzM1v3m3ZGbhwEOnVjljY6JJLx +MxagxnZZSAY424ZZ3t71E/Mn27dm2w+xFRuoy8JEjv1d+BT3eChM5KaNwrj0IO/y +u8kFIgWYA1vZ/15qMT+tyJTfyrNVV/7Df7TNeWyNqjJ5rBmt0M6NpHG7CrUSkBy9 +p8JhimgjP5r0FlEkgg+lyD+V79H98gQfVgP3pbJICz0SpBQf2F/2tyS4rLm+49rP +fcOajiXEuyhpcmzgusAj/1FjrtlynH1r9mnNaX4e+rLWzvU5AgMBAAGjUDBOMB0G +A1UdDgQWBBTkwyoJFGfYTVISTpM8E+igjdq28zAfBgNVHSMEGDAWgBTkwyoJFGfY +TVISTpM8E+igjdq28zAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4ICAQAR +OXnYwu3g1ZjHyley3fZI5aLPsaE17cOImVTehC8DcIphm2HOMR/hYTTL+V0G4P+u +gH+6xeRLKSHMHZTtSBIa6GDL03434y9CBuwGvAFCMU2GV8w92/Z7apkAhdLToZA/ +X/iWP2jeaVJhxgEcH8uPrnSlqoPBcKC9PrgUzQYfSZJkLmB+3jEa3HKruy1abJP5 +gAdQvwvcPpvYRnIzUc9fZODsVmlHVFBCl2dlu/iHh2h4GmL4Da2rRkUMlbVTdioB +UYIvMycdOkpH5wJftzw7cpjsudGas0PARDXCFfGyKhwBRFY7Xp7lbjtU5Rz0Gc04 +lPrhDf0pFE98Aw4jJRpFeWMjpXUEaG1cq7D641RpgcMfPFvOHY47rvDTS7XJOaUT +BwRjmDt896s6vMDcaG/uXJbQjuzmmx3W2Idyh3s5SI0GTHb0IwMKYb4eBUIpQOnB +cE77VnCYqKvN1NVYAqhWjXbY7XasZvszCRcOG+W3FqNaHOK/n/0ueb0uijdLan+U +f4p1bjbAox8eAOQS/8a3bzkJzdyBNUKGx1BIK2IBL9bn/HravSDOiNRSnZ/R3l9G +ZauX0tu7IIDlRCILXSyeazu0aj/vdT3YFQXPcvt5Fkf5wiNTo53f72/jYEJd6qph +WrpoKqrwGwTpRUCMhYIUt65hsTxCiJJ5nKe39h46sg== +-----END CERTIFICATE----- diff --git a/puppet/modules/nagios/files/plugins/check_dns2 b/puppet/modules/nagios/files/plugins/check_dns2 new file mode 100644 index 00000000..21956315 --- /dev/null +++ b/puppet/modules/nagios/files/plugins/check_dns2 @@ -0,0 +1,102 @@ +#!/bin/bash +# Written by Damien Gy +# damien.gy+nagiosexchange(AT)gmail.com +# 2007-09-28 + +PROGNAME=`basename $0` +REVISION=1.00 +TMP=/tmp/tmpdig +DIG=/usr/bin/dig + +print_revision() { + echo $PROGNAME $REVISION +} + +print_usage() { + echo "Usage:" + echo " $PROGNAME -c|--check <host> <type> <server>" + echo " $PROGNAME -h|--help" + echo " $PROGNAME -v|--version" +} + +print_help() { + print_revision + echo "" + print_usage + echo "Where:" + echo " host the name of the resource record to be looked up" + echo " type indicates the query required (any, a, mx, etc.)" + echo " server the name or IP address of the name server to query" + echo "" + echo " -h|--help prints this help screen" + echo "" + echo " -v|--version prints version and license information" + echo "" + echo " Created by Damien Gy, questions or problems e-mail damien.gy+nagiosexchange(AT)gmail.com" + echo "" +} + +check_dns() { + + if [ $# -ne 3 ] + then + echo "Number of arguments incorrect" + exit 3 + fi + if [ ! -e $DIG ] + then + echo "$DIG not found" + exit 3 + fi + $DIG $1 $2 @$3 > $TMP + + if ( grep "status" $TMP > /dev/null ) + then + # DNS server answered + if ( grep "NOERROR" $TMP > /dev/null ) + then + echo "DNS OK "`grep "time:" $TMP` + rm -f $TMP + exit 0 + else + echo "WARNING "`grep "time:" $TMP` + rm -f $TMP + exit 1 + fi + + else + # no answer + echo "CRITICAL - Connection timed out" + rm -f $TMP + exit 2 + fi +} + +case "$1" in +--help) + print_help + exit 0 + ;; +-h) + print_help + exit 0 + ;; +--version) + print_revision + exit 0 + ;; +-v) + print_revision + exit 0 + ;; +--check) + check_dns $2 $3 $4 + ;; +-c) + check_dns $2 $3 $4 + ;; +*) + print_usage + exit 3 + +esac diff --git a/puppet/modules/nagios/files/plugins/check_dnsbl b/puppet/modules/nagios/files/plugins/check_dnsbl new file mode 100644 index 00000000..93cea375 --- /dev/null +++ b/puppet/modules/nagios/files/plugins/check_dnsbl @@ -0,0 +1,107 @@ +#!/bin/sh +# +# dnsbl-check-nagios.sh +# +# (c) 2009 Damon Tajeddini & heise Netze +# +STATE_OK=0 +STATE_WARNING=1 +STATE_CRITICAL=2 +STATE_UNKNOWN=3 +STATE_DEPENDENT=4 + +FOUND_ADRESS=0 + +DNSBLlist=`grep -v ^# <<! +cbl.abuseat.org +dnsbl.ahbl.org +ircbl.ahbl.org +virbl.dnsbl.bit.nl +blackholes.five-ten-sg.com +dnsbl.inps.de +ix.dnsbl.manitu.net +no-more-funn.moensted.dk +combined.njabl.org +dnsbl.njabl.org +dnsbl.sorbs.net +bl.spamcannibal.org +bl.spamcop.net +sbl.spamhaus.org +xbl.spamhaus.org +pbl.spamhaus.org +dnsbl-1.uceprotect.net +# dnsbl-2.uceprotect.net +# dnsbl-3.uceprotect.net +psbl.surriel.com +l2.apews.org +dnsrbl.swinog.ch +db.wpbl.info +!` + +# reverse IP address +convertIP() +{ + set `IFS=".";echo $1` + echo $4.$3.$2.$1 +} + +usage() +{ + echo "Usage: $0 [-H] <host>] [-p]" + echo " -H check Host " + echo " -p print list of DNSBLs" + exit 3 +} + +# Checks the IP with list of DNSBL servers +check() +{ + count=0; + for i in $DNSBLlist + do + count=$(($count + 1)) + if nslookup $ip_arpa.$i | grep -q "127.0.0." ; + then + FOUND_ADRESS=$(($FOUND_ADRESS + 1)) + echo "DNSBL-Alarm: $ip is listed on $i" + fi + done + if [ $FOUND_ADRESS -ge 1 ] + then + exit 1 + fi + echo "OK - $ip not on $count DNSBLs" + exit 0 +} + +case $1 in + -H) + if [ -z "$2" ] + then + echo "ip address missing" + exit + fi + ip=$2 + ip_arpa=`convertIP $ip` + check;; + + -p) + for i in $DNSBLlist + do + echo $i + done + exit $STATE_WARNING + exit;; + + --help) + usage + exit;; + + *) + if [ -z "$1" ] + then + usage + fi + echo "unknown command: $1" + exit;; +esac diff --git a/puppet/modules/nagios/files/plugins/check_gpg b/puppet/modules/nagios/files/plugins/check_gpg new file mode 100644 index 00000000..eb9fa51f --- /dev/null +++ b/puppet/modules/nagios/files/plugins/check_gpg @@ -0,0 +1,115 @@ +#!/bin/bash +# +# Nagios plugin that checks whether a key ID has expired, or will expire within +# a certain time. +# +# note: the plugin will issue a critical state if the required key has been +# revoked. +# +# usage: check_gpg [-w <num_days>] [--gnupg-homedir <path>] <key_id> +# +# <key_id> is any PGP key ID that GnuPG accepts with "gpg --list-key <key_id>" +# +# The option -w parameter lets you specify the number of days within which key +# expiry will trigger a warning. e.g. if <key_id> expires within <num_days> +# days, make nagios issue a warning. +# +# num_days must be an integer value +# +# optionally, if the keyring directory you want GPG to use is not located in +# the user's ~/.gnupg, you can specify the path to the keyring directory with +# the --gnupg-homedir parameter. +# +# Thanks a bunch to Daniel Kahn Gillmor for providing example commands that +# made up most of the core of this plugin. +# +# Copyleft Gabriel Filion +# +# This plugin is released under the GPL v3+ license. To get a copy of the +# license text visit: https://www.gnu.org/licenses/gpl-3.0.txt +# +SECS_IN_DAY=86400 + +function debug () { + if [ -n "$DEBUG" ]; then + echo "$1" >&2 + fi +} + +debug "got args: $*" + +now=$(date +%s) +debug "current timestamp: $now" + +warning_threshold= +homedir= +homedir_path=~/.gnupg +for arg in $*; do + case $arg in + "-w") + if [ -z "$2" ]; then + echo "UNKNOWN: argument -w got no value. integer needed" + exit 3 + fi + if [ "`echo $2 | egrep ^[[:digit:]]+$`" = "" ]; then + echo "UNKNOWN: invalid value '$2' passed to -w. integer needed" + exit 3 + fi + warning_threshold=$(( $now + ($2*$SECS_IN_DAY) )) + debug "setting warning_threshold to '$warning_threshold'" + + shift 2 + ;; + "--gnupg-homedir") + if [ -z "$2" ]; then + echo "UNKNOWN: argument --gnupg-homedir got no value. path needed" + exit 3 + fi + if [ ! -d "$2" ]; then + echo "UNKNOWN: homedir '$2' does not exist or is not a directory" + exit 3 + fi + homedir_path=$2 + homedir="--homedir ${homedir_path}" + debug "setting homedir to '$homedir_path'" + + shift 2 + ;; + esac +done + +if [ -z "$1" ]; then + echo "UNKNOWN: must provide a key ID" + exit 3 +fi +key="$1" + +# GPG is too stupid to error out when asked to refresh a key that's not in the +# local keyring so we need to perform another call to verify this first. +output=$( { gpg $homedir --list-key "$key" >/dev/null && gpg $homedir --refresh --keyserver hkps://hkps.pool.sks-keyservers.net --keyserver-options ca-cert-file=$homedir_path/sks-keyservers.netCA.pem "$key" >/dev/null; } 2>&1 ) +if [ $? -ne 0 ]; then + echo "UNKNOWN: $output" + exit 3 +fi + +if [ "$(gpg $homedir --check-sig "$key" | grep "^rev!")" != "" ]; then + echo "CRITICAL: key '$key' has been revoked!" + exit 1 +fi + +for expiry in $(gpg $homedir --with-colons --fixed-list-mode --list-key "$key" 2>/dev/null | awk -F: '/^pub:/{ print $7 }'); +do + debug "expiry value: $expiry" + + if [ "$now" -gt "$expiry" ] ; then + printf "CRITICAL: %s has expired on %s\n" "$key" "$(date -d "$expiry seconds")"; + exit 1; + fi; + if [ -n "$warning_threshold" ] && [ "$warning_threshold" -gt "$expiry" ]; then + remaining=$(( ($expiry-$now) / $SECS_IN_DAY )) + printf "WARNING: %s expires in %s days\n" "$key" "$remaining"; + exit 2; + fi +done + +echo "OK: key '$key' has not expired." diff --git a/puppet/modules/nagios/files/plugins/check_horde_login b/puppet/modules/nagios/files/plugins/check_horde_login new file mode 100644 index 00000000..8c821e48 --- /dev/null +++ b/puppet/modules/nagios/files/plugins/check_horde_login @@ -0,0 +1,94 @@ +#!/bin/env python +# vi:si:et:sw=4:sts=4:ts=4 +# -*- coding: UTF-8 -*- +# -*- Mode: Python -*- +# +# Copyright (C) 2015 mh <mh@immerda.ch> + +# This file may be distributed and/or modified under the terms of +# the GNU General Public License version 2 as published by +# the Free Software Foundation. +# This file is distributed without any warranty; without even the implied +# warranty of merchantability or fitness for a particular purpose. +# + +import sys, os, requests, getopt +from time import time + +def usage(): + print sys.argv[0] + " -u username "+ \ + "-p password " + \ + "-s server path" + \ + "[-w warning_in_s] " + \ + "[-c critical_in_s]" + sys.exit(1) + +def main(): + try: + opts, args = getopt.getopt(sys.argv[1:], "u:p:s:h:w:c") + except getopt.GetoptError: + usage() + return 3 + + user = url = password = None + warning = 5 + critical = 10 + + for o, a in opts: + if o == "-u": + user = a + elif o == "-p": + password = a + elif o == "-w": + warning = a + elif o == "-c": + critical = a + elif o == "-s": + url = a + "/login.php" + elif o == '-h': + usage() + + if user == None or password == None or url == None: + usage() + + params = { 'horde_user': user, + 'horde_pass': password, + 'horde_select_view': 'auto', + 'anchor_string': '', + 'app': '', + 'login_post': 1, + 'new_lang': 'en_US', + 'url': '', + } + + + timestamp = time() + try: + r = requests.post(url, data=params, allow_redirects=False) + except Exception, e: + print "CRITICAL Horde Login Failed: %s" % e + sys.exit(2) + + timestamp = time() - timestamp + if r.status_code == 302: + if timestamp < warning: + status = "OK" + exitcode = 0 + if timestamp >= warning: + status = "WARNING" + exitcode = 1 + if timestamp >= critical: + status = "CRITICAL" + exitcode = 2 + else: + status = "ERROR" + exitcode = 2 + # on a successfully login we are redirected to the mailbox + print '%s Horde Login | response_time=%.3fs;%.3f;%.3f' % (status, timestamp, warning, critical) + sys.exit(exitcode) + + +if __name__ == "__main__": + sys.exit(main()) + + diff --git a/puppet/modules/nagios/files/plugins/check_imap_login b/puppet/modules/nagios/files/plugins/check_imap_login new file mode 100644 index 00000000..d059822b --- /dev/null +++ b/puppet/modules/nagios/files/plugins/check_imap_login @@ -0,0 +1,80 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +# -*- Mode: Python -*- +# +# Copyright (C) 2006 Bertera Pietro <pietro@bertera.it> +# Response time monitoring with perfdata modification by Ivan Savcic <isavcic@gmail.com> and Milos Buncic, 2012. +# From: https://github.com/isavcic/check_imap_login + +# This file may be distributed and/or modified under the terms of +# the GNU General Public License version 2 as published by +# the Free Software Foundation. +# This file is distributed without any warranty; without even the implied +# warranty of merchantability or fitness for a particular purpose. + +import sys, os, imaplib, getopt +from time import time + +def usage(): + print sys.argv[0] + " -u <user> -p <password> -H <host> [-s] -w <warning threshold (sec)> -c <critical threshold (sec)>\n -s is for using IMAPS" + +def main(): + try: + opts, args = getopt.getopt(sys.argv[1:], "u:p:sH:w:c:") + except getopt.GetoptError: + usage() + return 3 + + user = host = password = use_ssl = warning = critical = None + + for o, a in opts: + if o == "-u": + user = a + elif o == "-p": + password = a + elif o == "-s": + use_ssl = True + elif o == "-H": + host = a + elif o == "-w": + warning = float(a) + elif o == "-c": + critical = float(a) + + if user == None or password == None or host == None or warning == None or critical == None: + usage() + return 1 + + if use_ssl: + M = imaplib.IMAP4_SSL(host=host) + else: + M = imaplib.IMAP4(host) + + timestamp = time() + + try: + M.login(user, password) + except Exception, e: + print "CRITICAL IMAP Login Failed: %s" % e + return 2 + + M.logout() + + timestamp = time() - timestamp + + if timestamp < warning: + status = "OK" + exitcode = 0 + if timestamp >= warning: + status = "WARNING" + exitcode = 1 + if timestamp >= critical: + status = "CRITICAL" + exitcode = 2 + + print '%s IMAP Login | response_time=%.3fs;%.3f;%.3f' % (status, timestamp, warning, critical) + + return exitcode + +if __name__ == "__main__": + sys.exit(main()) diff --git a/puppet/modules/nagios/files/plugins/check_jabber_login b/puppet/modules/nagios/files/plugins/check_jabber_login new file mode 100644 index 00000000..dac0e1fe --- /dev/null +++ b/puppet/modules/nagios/files/plugins/check_jabber_login @@ -0,0 +1,30 @@ +#!/usr/bin/env ruby +require 'rubygems' +require 'xmpp4r' + + +def usage + puts "#{$0} jabberid password" + exit 3 +end + +usage unless ARGV.size == 2 + +begin + my_client = Jabber::Client.new(ARGV[0]) + my_client.connect + my_client.auth(ARGV[1]) +rescue Jabber::ClientAuthenticationFailure => detail + puts "CRITICAL: Login Error" + exit 2 +rescue Errno::ECONNREFUSED => detail + puts "CRITICAL: Connection refused" + exit 2 +rescue SocketError => detail + puts "CRITICAL: Socket Error" + exit 2 +#rescue +# puts "CRITICAL: Unknown Error" +# exit 2 +end +puts "OK: Login for #{ARGV[0]} successfull" diff --git a/puppet/modules/nagios/files/plugins/check_mysql_health b/puppet/modules/nagios/files/plugins/check_mysql_health new file mode 100755 index 00000000..9292ae09 --- /dev/null +++ b/puppet/modules/nagios/files/plugins/check_mysql_health @@ -0,0 +1,3780 @@ +#! /usr/bin/perl -w +# nagios: -epn + +my %ERRORS=( OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3 ); +my %ERRORCODES=( 0 => 'OK', 1 => 'WARNING', 2 => 'CRITICAL', 3 => 'UNKNOWN' ); +package DBD::MySQL::Server::Instance::Innodb; + +use strict; + +our @ISA = qw(DBD::MySQL::Server::Instance); + + +sub new { + my $class = shift; + my %params = @_; + my $self = { + handle => $params{handle}, + internals => undef, + warningrange => $params{warningrange}, + criticalrange => $params{criticalrange}, + }; + bless $self, $class; + $self->init(%params); + return $self; +} + +sub init { + my $self = shift; + my %params = @_; + $self->init_nagios(); + if ($params{mode} =~ /server::instance::innodb/) { + $self->{internals} = + DBD::MySQL::Server::Instance::Innodb::Internals->new(%params); + } +} + +sub nagios { + my $self = shift; + my %params = @_; + if ($params{mode} =~ /server::instance::innodb/) { + $self->{internals}->nagios(%params); + $self->merge_nagios($self->{internals}); + } +} + + +package DBD::MySQL::Server::Instance::Innodb::Internals; + +use strict; + +our @ISA = qw(DBD::MySQL::Server::Instance::Innodb); + +our $internals; # singleton, nur ein einziges mal instantiierbar + +sub new { + my $class = shift; + my %params = @_; + unless ($internals) { + $internals = { + handle => $params{handle}, + bufferpool_hitrate => undef, + wait_free => undef, + log_waits => undef, + have_innodb => undef, + warningrange => $params{warningrange}, + criticalrange => $params{criticalrange}, + }; + bless($internals, $class); + $internals->init(%params); + } + return($internals); +} + +sub init { + my $self = shift; + my %params = @_; + my $dummy; + $self->debug("enter init"); + $self->init_nagios(); + ($dummy, $self->{have_innodb}) + = $self->{handle}->fetchrow_array(q{ + SHOW VARIABLES LIKE 'have_innodb' + }); + if ($self->{have_innodb} eq "NO") { + $self->add_nagios_critical("the innodb engine has a problem (have_innodb=no)"); + } elsif ($self->{have_innodb} eq "DISABLED") { + # add_nagios_ok later + } elsif ($params{mode} =~ /server::instance::innodb::bufferpool::hitrate/) { + ($dummy, $self->{bufferpool_reads}) + = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Innodb_buffer_pool_reads' + }); + ($dummy, $self->{bufferpool_read_requests}) + = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Innodb_buffer_pool_read_requests' + }); + if (! defined $self->{bufferpool_reads}) { + $self->add_nagios_critical("no innodb buffer pool info available"); + } else { + $self->valdiff(\%params, qw(bufferpool_reads + bufferpool_read_requests)); + $self->{bufferpool_hitrate_now} = + $self->{delta_bufferpool_read_requests} > 0 ? + 100 - (100 * $self->{delta_bufferpool_reads} / + $self->{delta_bufferpool_read_requests}) : 100; + $self->{bufferpool_hitrate} = + $self->{bufferpool_read_requests} > 0 ? + 100 - (100 * $self->{bufferpool_reads} / + $self->{bufferpool_read_requests}) : 100; + } + } elsif ($params{mode} =~ /server::instance::innodb::bufferpool::waitfree/) { + ($dummy, $self->{bufferpool_wait_free}) + = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Innodb_buffer_pool_wait_free' + }); + if (! defined $self->{bufferpool_wait_free}) { + $self->add_nagios_critical("no innodb buffer pool info available"); + } else { + $self->valdiff(\%params, qw(bufferpool_wait_free)); + $self->{bufferpool_wait_free_rate} = + $self->{delta_bufferpool_wait_free} / $self->{delta_timestamp}; + } + } elsif ($params{mode} =~ /server::instance::innodb::logwaits/) { + ($dummy, $self->{log_waits}) + = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Innodb_log_waits' + }); + if (! defined $self->{log_waits}) { + $self->add_nagios_critical("no innodb log info available"); + } else { + $self->valdiff(\%params, qw(log_waits)); + $self->{log_waits_rate} = + $self->{delta_log_waits} / $self->{delta_timestamp}; + } + } elsif ($params{mode} =~ /server::instance::innodb::needoptimize/) { +#fragmentation=$(($datafree * 100 / $datalength)) + +#http://www.electrictoolbox.com/optimize-tables-mysql-php/ + my @result = $self->{handle}->fetchall_array(q{ +SHOW TABLE STATUS WHERE Data_free / Data_length > 0.1 AND Data_free > 102400 +}); +printf "%s\n", Data::Dumper::Dumper(\@result); + + } +} + +sub nagios { + my $self = shift; + my %params = @_; + my $now = $params{lookback} ? '_now' : ''; + if ($self->{have_innodb} eq "DISABLED") { + $self->add_nagios_ok("the innodb engine has been disabled"); + } elsif (! $self->{nagios_level}) { + if ($params{mode} =~ /server::instance::innodb::bufferpool::hitrate/) { + my $refkey = 'bufferpool_hitrate'.($params{lookback} ? '_now' : ''); + $self->add_nagios( + $self->check_thresholds($self->{$refkey}, "99:", "95:"), + sprintf "innodb buffer pool hitrate at %.2f%%", $self->{$refkey}); + $self->add_perfdata(sprintf "bufferpool_hitrate=%.2f%%;%s;%s;0;100", + $self->{bufferpool_hitrate}, + $self->{warningrange}, $self->{criticalrange}); + $self->add_perfdata(sprintf "bufferpool_hitrate_now=%.2f%%", + $self->{bufferpool_hitrate_now}); + } elsif ($params{mode} =~ /server::instance::innodb::bufferpool::waitfree/) { + $self->add_nagios( + $self->check_thresholds($self->{bufferpool_wait_free_rate}, "1", "10"), + sprintf "%ld innodb buffer pool waits in %ld seconds (%.4f/sec)", + $self->{delta_bufferpool_wait_free}, $self->{delta_timestamp}, + $self->{bufferpool_wait_free_rate}); + $self->add_perfdata(sprintf "bufferpool_free_waits_rate=%.4f;%s;%s;0;100", + $self->{bufferpool_wait_free_rate}, + $self->{warningrange}, $self->{criticalrange}); + } elsif ($params{mode} =~ /server::instance::innodb::logwaits/) { + $self->add_nagios( + $self->check_thresholds($self->{log_waits_rate}, "1", "10"), + sprintf "%ld innodb log waits in %ld seconds (%.4f/sec)", + $self->{delta_log_waits}, $self->{delta_timestamp}, + $self->{log_waits_rate}); + $self->add_perfdata(sprintf "innodb_log_waits_rate=%.4f;%s;%s;0;100", + $self->{log_waits_rate}, + $self->{warningrange}, $self->{criticalrange}); + } + } +} + + + + +package DBD::MySQL::Server::Instance::MyISAM; + +use strict; + +our @ISA = qw(DBD::MySQL::Server::Instance); + + +sub new { + my $class = shift; + my %params = @_; + my $self = { + handle => $params{handle}, + internals => undef, + warningrange => $params{warningrange}, + criticalrange => $params{criticalrange}, + }; + bless $self, $class; + $self->init(%params); + return $self; +} + +sub init { + my $self = shift; + my %params = @_; + $self->init_nagios(); + if ($params{mode} =~ /server::instance::myisam/) { + $self->{internals} = + DBD::MySQL::Server::Instance::MyISAM::Internals->new(%params); + } +} + +sub nagios { + my $self = shift; + my %params = @_; + if ($params{mode} =~ /server::instance::myisam/) { + $self->{internals}->nagios(%params); + $self->merge_nagios($self->{internals}); + } +} + + +package DBD::MySQL::Server::Instance::MyISAM::Internals; + +use strict; + +our @ISA = qw(DBD::MySQL::Server::Instance::MyISAM); + +our $internals; # singleton, nur ein einziges mal instantiierbar + +sub new { + my $class = shift; + my %params = @_; + unless ($internals) { + $internals = { + handle => $params{handle}, + keycache_hitrate => undef, + warningrange => $params{warningrange}, + criticalrange => $params{criticalrange}, + }; + bless($internals, $class); + $internals->init(%params); + } + return($internals); +} + +sub init { + my $self = shift; + my %params = @_; + my $dummy; + $self->debug("enter init"); + $self->init_nagios(); + if ($params{mode} =~ /server::instance::myisam::keycache::hitrate/) { + ($dummy, $self->{key_reads}) + = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Key_reads' + }); + ($dummy, $self->{key_read_requests}) + = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Key_read_requests' + }); + if (! defined $self->{key_read_requests}) { + $self->add_nagios_critical("no myisam keycache info available"); + } else { + $self->valdiff(\%params, qw(key_reads key_read_requests)); + $self->{keycache_hitrate} = + $self->{key_read_requests} > 0 ? + 100 - (100 * $self->{key_reads} / + $self->{key_read_requests}) : 100; + $self->{keycache_hitrate_now} = + $self->{delta_key_read_requests} > 0 ? + 100 - (100 * $self->{delta_key_reads} / + $self->{delta_key_read_requests}) : 100; + } + } elsif ($params{mode} =~ /server::instance::myisam::sonstnochwas/) { + } +} + +sub nagios { + my $self = shift; + my %params = @_; + if (! $self->{nagios_level}) { + if ($params{mode} =~ /server::instance::myisam::keycache::hitrate/) { + my $refkey = 'keycache_hitrate'.($params{lookback} ? '_now' : ''); + $self->add_nagios( + $self->check_thresholds($self->{$refkey}, "99:", "95:"), + sprintf "myisam keycache hitrate at %.2f%%", $self->{$refkey}); + $self->add_perfdata(sprintf "keycache_hitrate=%.2f%%;%s;%s", + $self->{keycache_hitrate}, + $self->{warningrange}, $self->{criticalrange}); + $self->add_perfdata(sprintf "keycache_hitrate_now=%.2f%%;%s;%s", + $self->{keycache_hitrate_now}, + $self->{warningrange}, $self->{criticalrange}); + } + } +} + + +package DBD::MySQL::Server::Instance::Replication; + +use strict; + +our @ISA = qw(DBD::MySQL::Server::Instance); + + +sub new { + my $class = shift; + my %params = @_; + my $self = { + handle => $params{handle}, + internals => undef, + warningrange => $params{warningrange}, + criticalrange => $params{criticalrange}, + }; + bless $self, $class; + $self->init(%params); + return $self; +} + +sub init { + my $self = shift; + my %params = @_; + $self->init_nagios(); + if ($params{mode} =~ /server::instance::replication/) { + $self->{internals} = + DBD::MySQL::Server::Instance::Replication::Internals->new(%params); + } +} + +sub nagios { + my $self = shift; + my %params = @_; + if ($params{mode} =~ /server::instance::replication/) { + $self->{internals}->nagios(%params); + $self->merge_nagios($self->{internals}); + } +} + + +package DBD::MySQL::Server::Instance::Replication::Internals; + +use strict; + +our @ISA = qw(DBD::MySQL::Server::Instance::Replication); + +our $internals; # singleton, nur ein einziges mal instantiierbar + +sub new { + my $class = shift; + my %params = @_; + unless ($internals) { + $internals = { + handle => $params{handle}, + seconds_behind_master => undef, + slave_io_running => undef, + slave_sql_running => undef, + warningrange => $params{warningrange}, + criticalrange => $params{criticalrange}, + }; + bless($internals, $class); + $internals->init(%params); + } + return($internals); +} + +sub init { + my $self = shift; + my %params = @_; + $self->debug("enter init"); + $self->init_nagios(); + if ($params{mode} =~ /server::instance::replication::slavelag/) { + # "show slave status", "Seconds_Behind_Master" + my $slavehash = $self->{handle}->selectrow_hashref(q{ + SHOW SLAVE STATUS + }); + if ((! defined $slavehash->{Seconds_Behind_Master}) && + (lc $slavehash->{Slave_IO_Running} eq 'no')) { + $self->add_nagios_critical( + "unable to get slave lag, because io thread is not running"); + } elsif (! defined $slavehash->{Seconds_Behind_Master}) { + $self->add_nagios_critical(sprintf "unable to get replication info%s", + $self->{handle}->{errstr} ? $self->{handle}->{errstr} : ""); + } else { + $self->{seconds_behind_master} = $slavehash->{Seconds_Behind_Master}; + } + } elsif ($params{mode} =~ /server::instance::replication::slaveiorunning/) { + # "show slave status", "Slave_IO_Running" + my $slavehash = $self->{handle}->selectrow_hashref(q{ + SHOW SLAVE STATUS + }); + if (! defined $slavehash->{Slave_IO_Running}) { + $self->add_nagios_critical(sprintf "unable to get replication info%s", + $self->{handle}->{errstr} ? $self->{handle}->{errstr} : ""); + } else { + $self->{slave_io_running} = $slavehash->{Slave_IO_Running}; + } + } elsif ($params{mode} =~ /server::instance::replication::slavesqlrunning/) { + # "show slave status", "Slave_SQL_Running" + my $slavehash = $self->{handle}->selectrow_hashref(q{ + SHOW SLAVE STATUS + }); + if (! defined $slavehash->{Slave_SQL_Running}) { + $self->add_nagios_critical(sprintf "unable to get replication info%s", + $self->{handle}->{errstr} ? $self->{handle}->{errstr} : ""); + } else { + $self->{slave_sql_running} = $slavehash->{Slave_SQL_Running}; + } + } +} + +sub nagios { + my $self = shift; + my %params = @_; + if (! $self->{nagios_level}) { + if ($params{mode} =~ /server::instance::replication::slavelag/) { + $self->add_nagios( + $self->check_thresholds($self->{seconds_behind_master}, "10", "20"), + sprintf "Slave is %d seconds behind master", + $self->{seconds_behind_master}); + $self->add_perfdata(sprintf "slave_lag=%d;%s;%s", + $self->{seconds_behind_master}, + $self->{warningrange}, $self->{criticalrange}); + } elsif ($params{mode} =~ /server::instance::replication::slaveiorunning/) { + if (lc $self->{slave_io_running} eq "yes") { + $self->add_nagios_ok("Slave io is running"); + } else { + $self->add_nagios_critical("Slave io is not running"); + } + } elsif ($params{mode} =~ /server::instance::replication::slavesqlrunning/) { + if (lc $self->{slave_sql_running} eq "yes") { + $self->add_nagios_ok("Slave sql is running"); + } else { + $self->add_nagios_critical("Slave sql is not running"); + } + } + } +} + + + +package DBD::MySQL::Server::Instance; + +use strict; + +our @ISA = qw(DBD::MySQL::Server); + + +sub new { + my $class = shift; + my %params = @_; + my $self = { + handle => $params{handle}, + uptime => $params{uptime}, + warningrange => $params{warningrange}, + criticalrange => $params{criticalrange}, + threads_connected => undef, + threads_created => undef, + connections => undef, + threadcache_hitrate => undef, + querycache_hitrate => undef, + lowmem_prunes_per_sec => undef, + slow_queries_per_sec => undef, + longrunners => undef, + tablecache_hitrate => undef, + index_usage => undef, + engine_innodb => undef, + engine_myisam => undef, + replication => undef, + }; + bless $self, $class; + $self->init(%params); + return $self; +} + +sub init { + my $self = shift; + my %params = @_; + my $dummy; + $self->init_nagios(); + if ($params{mode} =~ /server::instance::connectedthreads/) { + ($dummy, $self->{threads_connected}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Threads_connected' + }); + } elsif ($params{mode} =~ /server::instance::createdthreads/) { + ($dummy, $self->{threads_created}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Threads_created' + }); + $self->valdiff(\%params, qw(threads_created)); + $self->{threads_created_per_sec} = $self->{delta_threads_created} / + $self->{delta_timestamp}; + } elsif ($params{mode} =~ /server::instance::runningthreads/) { + ($dummy, $self->{threads_running}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Threads_running' + }); + } elsif ($params{mode} =~ /server::instance::cachedthreads/) { + ($dummy, $self->{threads_cached}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Threads_cached' + }); + } elsif ($params{mode} =~ /server::instance::abortedconnects/) { + ($dummy, $self->{connects_aborted}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Aborted_connects' + }); + $self->valdiff(\%params, qw(connects_aborted)); + $self->{connects_aborted_per_sec} = $self->{delta_connects_aborted} / + $self->{delta_timestamp}; + } elsif ($params{mode} =~ /server::instance::abortedclients/) { + ($dummy, $self->{clients_aborted}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Aborted_clients' + }); + $self->valdiff(\%params, qw(clients_aborted)); + $self->{clients_aborted_per_sec} = $self->{delta_clients_aborted} / + $self->{delta_timestamp}; + } elsif ($params{mode} =~ /server::instance::threadcachehitrate/) { + ($dummy, $self->{threads_created}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Threads_created' + }); + ($dummy, $self->{connections}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Connections' + }); + $self->valdiff(\%params, qw(threads_created connections)); + if ($self->{delta_connections} > 0) { + $self->{threadcache_hitrate_now} = + 100 - ($self->{delta_threads_created} * 100.0 / + $self->{delta_connections}); + } else { + $self->{threadcache_hitrate_now} = 100; + } + $self->{threadcache_hitrate} = 100 - + ($self->{threads_created} * 100.0 / $self->{connections}); + $self->{connections_per_sec} = $self->{delta_connections} / + $self->{delta_timestamp}; + } elsif ($params{mode} =~ /server::instance::querycachehitrate/) { + ($dummy, $self->{com_select}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Com_select' + }); + ($dummy, $self->{qcache_hits}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Qcache_hits' + }); + # SHOW VARIABLES WHERE Variable_name = 'have_query_cache' for 5.x, but LIKE is compatible + ($dummy, $self->{have_query_cache}) = $self->{handle}->fetchrow_array(q{ + SHOW VARIABLES LIKE 'have_query_cache' + }); + # SHOW VARIABLES WHERE Variable_name = 'query_cache_size' + ($dummy, $self->{query_cache_size}) = $self->{handle}->fetchrow_array(q{ + SHOW VARIABLES LIKE 'query_cache_size' + }); + $self->valdiff(\%params, qw(com_select qcache_hits)); + $self->{querycache_hitrate_now} = + ($self->{delta_com_select} + $self->{delta_qcache_hits}) > 0 ? + 100 * $self->{delta_qcache_hits} / + ($self->{delta_com_select} + $self->{delta_qcache_hits}) : + 0; + $self->{querycache_hitrate} = + 100 * $self->{qcache_hits} / ($self->{com_select} + $self->{qcache_hits}); + $self->{selects_per_sec} = + $self->{delta_com_select} / $self->{delta_timestamp}; + } elsif ($params{mode} =~ /server::instance::querycachelowmemprunes/) { + ($dummy, $self->{lowmem_prunes}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Qcache_lowmem_prunes' + }); + $self->valdiff(\%params, qw(lowmem_prunes)); + $self->{lowmem_prunes_per_sec} = $self->{delta_lowmem_prunes} / + $self->{delta_timestamp}; + } elsif ($params{mode} =~ /server::instance::slowqueries/) { + ($dummy, $self->{slow_queries}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Slow_queries' + }); + $self->valdiff(\%params, qw(slow_queries)); + $self->{slow_queries_per_sec} = $self->{delta_slow_queries} / + $self->{delta_timestamp}; + } elsif ($params{mode} =~ /server::instance::longprocs/) { + if (DBD::MySQL::Server::return_first_server()->version_is_minimum("5.1")) { + ($self->{longrunners}) = $self->{handle}->fetchrow_array(q{ + SELECT + COUNT(*) + FROM + information_schema.processlist + WHERE user <> 'replication' + AND id <> CONNECTION_ID() + AND time > 60 + AND command <> 'Sleep' + }); + } else { + $self->{longrunners} = 0 if ! defined $self->{longrunners}; + foreach ($self->{handle}->fetchall_array(q{ + SHOW PROCESSLIST + })) { + my($id, $user, $host, $db, $command, $tme, $state, $info) = @{$_}; + if (($user ne 'replication') && + ($tme > 60) && + ($command ne 'Sleep')) { + $self->{longrunners}++; + } + } + } + } elsif ($params{mode} =~ /server::instance::tablecachehitrate/) { + ($dummy, $self->{open_tables}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Open_tables' + }); + ($dummy, $self->{opened_tables}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Opened_tables' + }); + if (DBD::MySQL::Server::return_first_server()->version_is_minimum("5.1.3")) { + # SHOW VARIABLES WHERE Variable_name = 'table_open_cache' + ($dummy, $self->{table_cache}) = $self->{handle}->fetchrow_array(q{ + SHOW VARIABLES LIKE 'table_open_cache' + }); + } else { + # SHOW VARIABLES WHERE Variable_name = 'table_cache' + ($dummy, $self->{table_cache}) = $self->{handle}->fetchrow_array(q{ + SHOW VARIABLES LIKE 'table_cache' + }); + } + $self->{table_cache} ||= 0; + #$self->valdiff(\%params, qw(open_tables opened_tables table_cache)); + # _now ist hier sinnlos, da opened_tables waechst, aber open_tables wieder + # schrumpfen kann weil tabellen geschlossen werden. + if ($self->{opened_tables} != 0 && $self->{table_cache} != 0) { + $self->{tablecache_hitrate} = + 100 * $self->{open_tables} / $self->{opened_tables}; + $self->{tablecache_fillrate} = + 100 * $self->{open_tables} / $self->{table_cache}; + } elsif ($self->{opened_tables} == 0 && $self->{table_cache} != 0) { + $self->{tablecache_hitrate} = 100; + $self->{tablecache_fillrate} = + 100 * $self->{open_tables} / $self->{table_cache}; + } else { + $self->{tablecache_hitrate} = 0; + $self->{tablecache_fillrate} = 0; + $self->add_nagios_critical("no table cache"); + } + } elsif ($params{mode} =~ /server::instance::tablelockcontention/) { + ($dummy, $self->{table_locks_waited}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Table_locks_waited' + }); + ($dummy, $self->{table_locks_immediate}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Table_locks_immediate' + }); + $self->valdiff(\%params, qw(table_locks_waited table_locks_immediate)); + $self->{table_lock_contention} = + ($self->{table_locks_waited} + $self->{table_locks_immediate}) > 0 ? + 100 * $self->{table_locks_waited} / + ($self->{table_locks_waited} + $self->{table_locks_immediate}) : + 100; + $self->{table_lock_contention_now} = + ($self->{delta_table_locks_waited} + $self->{delta_table_locks_immediate}) > 0 ? + 100 * $self->{delta_table_locks_waited} / + ($self->{delta_table_locks_waited} + $self->{delta_table_locks_immediate}) : + 100; + } elsif ($params{mode} =~ /server::instance::tableindexusage/) { + # http://johnjacobm.wordpress.com/2007/06/ + # formula for calculating the percentage of full table scans + ($dummy, $self->{handler_read_first}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Handler_read_first' + }); + ($dummy, $self->{handler_read_key}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Handler_read_key' + }); + ($dummy, $self->{handler_read_next}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Handler_read_next' + }); + ($dummy, $self->{handler_read_prev}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Handler_read_prev' + }); + ($dummy, $self->{handler_read_rnd}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Handler_read_rnd' + }); + ($dummy, $self->{handler_read_rnd_next}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Handler_read_rnd_next' + }); + $self->valdiff(\%params, qw(handler_read_first handler_read_key + handler_read_next handler_read_prev handler_read_rnd + handler_read_rnd_next)); + my $delta_reads = $self->{delta_handler_read_first} + + $self->{delta_handler_read_key} + + $self->{delta_handler_read_next} + + $self->{delta_handler_read_prev} + + $self->{delta_handler_read_rnd} + + $self->{delta_handler_read_rnd_next}; + my $reads = $self->{handler_read_first} + + $self->{handler_read_key} + + $self->{handler_read_next} + + $self->{handler_read_prev} + + $self->{handler_read_rnd} + + $self->{handler_read_rnd_next}; + $self->{index_usage_now} = ($delta_reads == 0) ? 0 : + 100 - (100.0 * ($self->{delta_handler_read_rnd} + + $self->{delta_handler_read_rnd_next}) / + $delta_reads); + $self->{index_usage} = ($reads == 0) ? 0 : + 100 - (100.0 * ($self->{handler_read_rnd} + + $self->{handler_read_rnd_next}) / + $reads); + } elsif ($params{mode} =~ /server::instance::tabletmpondisk/) { + ($dummy, $self->{created_tmp_tables}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Created_tmp_tables' + }); + ($dummy, $self->{created_tmp_disk_tables}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Created_tmp_disk_tables' + }); + $self->valdiff(\%params, qw(created_tmp_tables created_tmp_disk_tables)); + $self->{pct_tmp_on_disk} = $self->{created_tmp_tables} > 0 ? + 100 * $self->{created_tmp_disk_tables} / $self->{created_tmp_tables} : + 100; + $self->{pct_tmp_on_disk_now} = $self->{delta_created_tmp_tables} > 0 ? + 100 * $self->{delta_created_tmp_disk_tables} / $self->{delta_created_tmp_tables} : + 100; + } elsif ($params{mode} =~ /server::instance::openfiles/) { + ($dummy, $self->{open_files_limit}) = $self->{handle}->fetchrow_array(q{ + SHOW VARIABLES LIKE 'open_files_limit' + }); + ($dummy, $self->{open_files}) = $self->{handle}->fetchrow_array(q{ + SHOW /*!50000 global */ STATUS LIKE 'Open_files' + }); + $self->{pct_open_files} = 100 * $self->{open_files} / $self->{open_files_limit}; + } elsif ($params{mode} =~ /server::instance::needoptimize/) { + $self->{fragmented} = []; + #http://www.electrictoolbox.com/optimize-tables-mysql-php/ + my @result = $self->{handle}->fetchall_array(q{ + SHOW TABLE STATUS + }); + foreach (@result) { + my ($name, $engine, $data_length, $data_free) = + ($_->[0], $_->[1], $_->[6 ], $_->[9]); + next if ($params{name} && $params{name} ne $name); + my $fragmentation = $data_length ? $data_free * 100 / $data_length : 0; + push(@{$self->{fragmented}}, + [$name, $fragmentation, $data_length, $data_free]); + } + } elsif ($params{mode} =~ /server::instance::myisam/) { + $self->{engine_myisam} = DBD::MySQL::Server::Instance::MyISAM->new( + %params + ); + } elsif ($params{mode} =~ /server::instance::innodb/) { + $self->{engine_innodb} = DBD::MySQL::Server::Instance::Innodb->new( + %params + ); + } elsif ($params{mode} =~ /server::instance::replication/) { + $self->{replication} = DBD::MySQL::Server::Instance::Replication->new( + %params + ); + } +} + +sub nagios { + my $self = shift; + my %params = @_; + if (! $self->{nagios_level}) { + if ($params{mode} =~ /server::instance::connectedthreads/) { + $self->add_nagios( + $self->check_thresholds($self->{threads_connected}, 10, 20), + sprintf "%d client connection threads", $self->{threads_connected}); + $self->add_perfdata(sprintf "threads_connected=%d;%d;%d", + $self->{threads_connected}, + $self->{warningrange}, $self->{criticalrange}); + } elsif ($params{mode} =~ /server::instance::createdthreads/) { + $self->add_nagios( + $self->check_thresholds($self->{threads_created_per_sec}, 10, 20), + sprintf "%.2f threads created/sec", $self->{threads_created_per_sec}); + $self->add_perfdata(sprintf "threads_created_per_sec=%.2f;%.2f;%.2f", + $self->{threads_created_per_sec}, + $self->{warningrange}, $self->{criticalrange}); + } elsif ($params{mode} =~ /server::instance::runningthreads/) { + $self->add_nagios( + $self->check_thresholds($self->{threads_running}, 10, 20), + sprintf "%d running threads", $self->{threads_running}); + $self->add_perfdata(sprintf "threads_running=%d;%d;%d", + $self->{threads_running}, + $self->{warningrange}, $self->{criticalrange}); + } elsif ($params{mode} =~ /server::instance::cachedthreads/) { + $self->add_nagios( + $self->check_thresholds($self->{threads_cached}, 10, 20), + sprintf "%d cached threads", $self->{threads_cached}); + $self->add_perfdata(sprintf "threads_cached=%d;%d;%d", + $self->{threads_cached}, + $self->{warningrange}, $self->{criticalrange}); + } elsif ($params{mode} =~ /server::instance::abortedconnects/) { + $self->add_nagios( + $self->check_thresholds($self->{connects_aborted_per_sec}, 1, 5), + sprintf "%.2f aborted connections/sec", $self->{connects_aborted_per_sec}); + $self->add_perfdata(sprintf "connects_aborted_per_sec=%.2f;%.2f;%.2f", + $self->{connects_aborted_per_sec}, + $self->{warningrange}, $self->{criticalrange}); + } elsif ($params{mode} =~ /server::instance::abortedclients/) { + $self->add_nagios( + $self->check_thresholds($self->{clients_aborted_per_sec}, 1, 5), + sprintf "%.2f aborted (client died) connections/sec", $self->{clients_aborted_per_sec}); + $self->add_perfdata(sprintf "clients_aborted_per_sec=%.2f;%.2f;%.2f", + $self->{clients_aborted_per_sec}, + $self->{warningrange}, $self->{criticalrange}); + } elsif ($params{mode} =~ /server::instance::threadcachehitrate/) { + my $refkey = 'threadcache_hitrate'.($params{lookback} ? '_now' : ''); + $self->add_nagios( + $self->check_thresholds($self->{$refkey}, "90:", "80:"), + sprintf "thread cache hitrate %.2f%%", $self->{$refkey}); + $self->add_perfdata(sprintf "thread_cache_hitrate=%.2f%%;%s;%s", + $self->{threadcache_hitrate}, + $self->{warningrange}, $self->{criticalrange}); + $self->add_perfdata(sprintf "thread_cache_hitrate_now=%.2f%%", + $self->{threadcache_hitrate_now}); + $self->add_perfdata(sprintf "connections_per_sec=%.2f", + $self->{connections_per_sec}); + } elsif ($params{mode} =~ /server::instance::querycachehitrate/) { + my $refkey = 'querycache_hitrate'.($params{lookback} ? '_now' : ''); + if ((lc $self->{have_query_cache} eq 'yes') && ($self->{query_cache_size})) { + $self->add_nagios( + $self->check_thresholds($self->{$refkey}, "90:", "80:"), + sprintf "query cache hitrate %.2f%%", $self->{$refkey}); + } else { + $self->check_thresholds($self->{$refkey}, "90:", "80:"); + $self->add_nagios_ok( + sprintf "query cache hitrate %.2f%% (because it's turned off)", + $self->{querycache_hitrate}); + } + $self->add_perfdata(sprintf "qcache_hitrate=%.2f%%;%s;%s", + $self->{querycache_hitrate}, + $self->{warningrange}, $self->{criticalrange}); + $self->add_perfdata(sprintf "qcache_hitrate_now=%.2f%%", + $self->{querycache_hitrate_now}); + $self->add_perfdata(sprintf "selects_per_sec=%.2f", + $self->{selects_per_sec}); + } elsif ($params{mode} =~ /server::instance::querycachelowmemprunes/) { + $self->add_nagios( + $self->check_thresholds($self->{lowmem_prunes_per_sec}, "1", "10"), + sprintf "%d query cache lowmem prunes in %d seconds (%.2f/sec)", + $self->{delta_lowmem_prunes}, $self->{delta_timestamp}, + $self->{lowmem_prunes_per_sec}); + $self->add_perfdata(sprintf "qcache_lowmem_prunes_rate=%.2f;%s;%s", + $self->{lowmem_prunes_per_sec}, + $self->{warningrange}, $self->{criticalrange}); + } elsif ($params{mode} =~ /server::instance::slowqueries/) { + $self->add_nagios( + $self->check_thresholds($self->{slow_queries_per_sec}, "0.1", "1"), + sprintf "%d slow queries in %d seconds (%.2f/sec)", + $self->{delta_slow_queries}, $self->{delta_timestamp}, + $self->{slow_queries_per_sec}); + $self->add_perfdata(sprintf "slow_queries_rate=%.2f%%;%s;%s", + $self->{slow_queries_per_sec}, + $self->{warningrange}, $self->{criticalrange}); + } elsif ($params{mode} =~ /server::instance::longprocs/) { + $self->add_nagios( + $self->check_thresholds($self->{longrunners}, 10, 20), + sprintf "%d long running processes", $self->{longrunners}); + $self->add_perfdata(sprintf "long_running_procs=%d;%d;%d", + $self->{longrunners}, + $self->{warningrange}, $self->{criticalrange}); + } elsif ($params{mode} =~ /server::instance::tablecachehitrate/) { + if ($self->{tablecache_fillrate} < 95) { + $self->add_nagios_ok( + sprintf "table cache hitrate %.2f%%, %.2f%% filled", + $self->{tablecache_hitrate}, + $self->{tablecache_fillrate}); + $self->check_thresholds($self->{tablecache_hitrate}, "99:", "95:"); + } else { + $self->add_nagios( + $self->check_thresholds($self->{tablecache_hitrate}, "99:", "95:"), + sprintf "table cache hitrate %.2f%%", $self->{tablecache_hitrate}); + } + $self->add_perfdata(sprintf "tablecache_hitrate=%.2f%%;%s;%s", + $self->{tablecache_hitrate}, + $self->{warningrange}, $self->{criticalrange}); + $self->add_perfdata(sprintf "tablecache_fillrate=%.2f%%", + $self->{tablecache_fillrate}); + } elsif ($params{mode} =~ /server::instance::tablelockcontention/) { + my $refkey = 'table_lock_contention'.($params{lookback} ? '_now' : ''); + if ($self->{uptime} > 10800) { # MySQL Bug #30599 + $self->add_nagios( + $self->check_thresholds($self->{$refkey}, "1", "2"), + sprintf "table lock contention %.2f%%", $self->{$refkey}); + } else { + $self->check_thresholds($self->{$refkey}, "1", "2"); + $self->add_nagios_ok( + sprintf "table lock contention %.2f%% (uptime < 10800)", + $self->{$refkey}); + } + $self->add_perfdata(sprintf "tablelock_contention=%.2f%%;%s;%s", + $self->{table_lock_contention}, + $self->{warningrange}, $self->{criticalrange}); + $self->add_perfdata(sprintf "tablelock_contention_now=%.2f%%", + $self->{table_lock_contention_now}); + } elsif ($params{mode} =~ /server::instance::tableindexusage/) { + my $refkey = 'index_usage'.($params{lookback} ? '_now' : ''); + $self->add_nagios( + $self->check_thresholds($self->{$refkey}, "90:", "80:"), + sprintf "index usage %.2f%%", $self->{$refkey}); + $self->add_perfdata(sprintf "index_usage=%.2f%%;%s;%s", + $self->{index_usage}, + $self->{warningrange}, $self->{criticalrange}); + $self->add_perfdata(sprintf "index_usage_now=%.2f%%", + $self->{index_usage_now}); + } elsif ($params{mode} =~ /server::instance::tabletmpondisk/) { + my $refkey = 'pct_tmp_on_disk'.($params{lookback} ? '_now' : ''); + $self->add_nagios( + $self->check_thresholds($self->{$refkey}, "25", "50"), + sprintf "%.2f%% of %d tables were created on disk", + $self->{$refkey}, $self->{delta_created_tmp_tables}); + $self->add_perfdata(sprintf "pct_tmp_table_on_disk=%.2f%%;%s;%s", + $self->{pct_tmp_on_disk}, + $self->{warningrange}, $self->{criticalrange}); + $self->add_perfdata(sprintf "pct_tmp_table_on_disk_now=%.2f%%", + $self->{pct_tmp_on_disk_now}); + } elsif ($params{mode} =~ /server::instance::openfiles/) { + $self->add_nagios( + $self->check_thresholds($self->{pct_open_files}, 80, 95), + sprintf "%.2f%% of the open files limit reached (%d of max. %d)", + $self->{pct_open_files}, + $self->{open_files}, $self->{open_files_limit}); + $self->add_perfdata(sprintf "pct_open_files=%.3f%%;%.3f;%.3f", + $self->{pct_open_files}, + $self->{warningrange}, + $self->{criticalrange}); + $self->add_perfdata(sprintf "open_files=%d;%d;%d", + $self->{open_files}, + $self->{open_files_limit} * $self->{warningrange} / 100, + $self->{open_files_limit} * $self->{criticalrange} / 100); + } elsif ($params{mode} =~ /server::instance::needoptimize/) { + foreach (@{$self->{fragmented}}) { + $self->add_nagios( + $self->check_thresholds($_->[1], 10, 25), + sprintf "table %s is %.2f%% fragmented", $_->[0], $_->[1]); + if ($params{name}) { + $self->add_perfdata(sprintf "'%s_frag'=%.2f%%;%d;%d", + $_->[0], $_->[1], $self->{warningrange}, $self->{criticalrange}); + } + } + } elsif ($params{mode} =~ /server::instance::myisam/) { + $self->{engine_myisam}->nagios(%params); + $self->merge_nagios($self->{engine_myisam}); + } elsif ($params{mode} =~ /server::instance::innodb/) { + $self->{engine_innodb}->nagios(%params); + $self->merge_nagios($self->{engine_innodb}); + } elsif ($params{mode} =~ /server::instance::replication/) { + $self->{replication}->nagios(%params); + $self->merge_nagios($self->{replication}); + } + } +} + + + +package DBD::MySQL::Server; + +use strict; +use Time::HiRes; +use IO::File; +use File::Copy 'cp'; +use Data::Dumper; + + +{ + our $verbose = 0; + our $scream = 0; # scream if something is not implemented + our $access = "dbi"; # how do we access the database. + our $my_modules_dyn_dir = ""; # where we look for self-written extensions + + my @servers = (); + my $initerrors = undef; + + sub add_server { + push(@servers, shift); + } + + sub return_servers { + return @servers; + } + + sub return_first_server() { + return $servers[0]; + } + +} + +sub new { + my $class = shift; + my %params = @_; + my $self = { + access => $params{method} || 'dbi', + hostname => $params{hostname}, + database => $params{database} || 'information_schema', + port => $params{port}, + socket => $params{socket}, + username => $params{username}, + password => $params{password}, + timeout => $params{timeout}, + warningrange => $params{warningrange}, + criticalrange => $params{criticalrange}, + verbose => $params{verbose}, + report => $params{report}, + labelformat => $params{labelformat}, + version => 'unknown', + instance => undef, + handle => undef, + }; + bless $self, $class; + $self->init_nagios(); + if ($self->dbconnect(%params)) { + ($self->{dummy}, $self->{version}) = $self->{handle}->fetchrow_array( + #q{ SHOW VARIABLES WHERE Variable_name = 'version' } + q{ SHOW VARIABLES LIKE 'version' } + ); + $self->{version} = (split "-", $self->{version})[0]; + ($self->{dummy}, $self->{uptime}) = $self->{handle}->fetchrow_array( + q{ SHOW STATUS LIKE 'Uptime' } + ); + DBD::MySQL::Server::add_server($self); + $self->init(%params); + } + return $self; +} + +sub init { + my $self = shift; + my %params = @_; + $params{handle} = $self->{handle}; + $params{uptime} = $self->{uptime}; + $self->set_global_db_thresholds(\%params); + if ($params{mode} =~ /^server::instance/) { + $self->{instance} = DBD::MySQL::Server::Instance->new(%params); + } elsif ($params{mode} =~ /^server::sql/) { + $self->set_local_db_thresholds(%params); + if ($params{regexp}) { + # sql output is treated as text + if ($params{name2} eq $params{name}) { + $self->add_nagios_unknown(sprintf "where's the regexp????"); + } else { + $self->{genericsql} = + $self->{handle}->fetchrow_array($params{selectname}); + if (! defined $self->{genericsql}) { + $self->add_nagios_unknown(sprintf "got no valid response for %s", + $params{selectname}); + } + } + } else { + # sql output must be a number (or array of numbers) + @{$self->{genericsql}} = + $self->{handle}->fetchrow_array($params{selectname}); + if (! (defined $self->{genericsql} && + (scalar(grep { /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/ } @{$self->{genericsql}})) == + scalar(@{$self->{genericsql}}))) { + $self->add_nagios_unknown(sprintf "got no valid response for %s", + $params{selectname}); + } else { + # name2 in array + # units in array + } + } + } elsif ($params{mode} =~ /^server::uptime/) { + # already set with the connection. but use minutes here + } elsif ($params{mode} =~ /^server::connectiontime/) { + $self->{connection_time} = $self->{tac} - $self->{tic}; + } elsif ($params{mode} =~ /^my::([^:.]+)/) { + my $class = $1; + my $loaderror = undef; + substr($class, 0, 1) = uc substr($class, 0, 1); + foreach my $libpath (split(":", $DBD::MySQL::Server::my_modules_dyn_dir)) { + foreach my $extmod (glob $libpath."/CheckMySQLHealth*.pm") { + eval { + $self->trace(sprintf "loading module %s", $extmod); + require $extmod; + }; + if ($@) { + $loaderror = $extmod; + $self->trace(sprintf "failed loading module %s: %s", $extmod, $@); + } + } + } + my $obj = { + handle => $params{handle}, + warningrange => $params{warningrange}, + criticalrange => $params{criticalrange}, + }; + bless $obj, "My$class"; + $self->{my} = $obj; + if ($self->{my}->isa("DBD::MySQL::Server")) { + my $dos_init = $self->can("init"); + my $dos_nagios = $self->can("nagios"); + my $my_init = $self->{my}->can("init"); + my $my_nagios = $self->{my}->can("nagios"); + if ($my_init == $dos_init) { + $self->add_nagios_unknown( + sprintf "Class %s needs an init() method", ref($self->{my})); + } elsif ($my_nagios == $dos_nagios) { + $self->add_nagios_unknown( + sprintf "Class %s needs a nagios() method", ref($self->{my})); + } else { + $self->{my}->init_nagios(%params); + $self->{my}->init(%params); + } + } else { + $self->add_nagios_unknown( + sprintf "Class %s is not a subclass of DBD::MySQL::Server%s", + ref($self->{my}), + $loaderror ? sprintf " (syntax error in %s?)", $loaderror : "" ); + } + } else { + printf "broken mode %s\n", $params{mode}; + } +} + +sub dump { + my $self = shift; + my $message = shift || ""; + printf "%s %s\n", $message, Data::Dumper::Dumper($self); +} + +sub nagios { + my $self = shift; + my %params = @_; + if (! $self->{nagios_level}) { + if ($params{mode} =~ /^server::instance/) { + $self->{instance}->nagios(%params); + $self->merge_nagios($self->{instance}); + } elsif ($params{mode} =~ /^server::database/) { + $self->{database}->nagios(%params); + $self->merge_nagios($self->{database}); + } elsif ($params{mode} =~ /^server::uptime/) { + $self->add_nagios( + $self->check_thresholds($self->{uptime} / 60, "10:", "5:"), + sprintf "database is up since %d minutes", $self->{uptime} / 60); + $self->add_perfdata(sprintf "uptime=%ds", + $self->{uptime}); + } elsif ($params{mode} =~ /^server::connectiontime/) { + $self->add_nagios( + $self->check_thresholds($self->{connection_time}, 1, 5), + sprintf "%.2f seconds to connect as %s", + $self->{connection_time}, ($self->{username} || getpwuid($<))); + $self->add_perfdata(sprintf "connection_time=%.4fs;%d;%d", + $self->{connection_time}, + $self->{warningrange}, $self->{criticalrange}); + } elsif ($params{mode} =~ /^server::sql/) { + if ($params{regexp}) { + if (substr($params{name2}, 0, 1) eq '!') { + $params{name2} =~ s/^!//; + if ($self->{genericsql} !~ /$params{name2}/) { + $self->add_nagios_ok( + sprintf "output %s does not match pattern %s", + $self->{genericsql}, $params{name2}); + } else { + $self->add_nagios_critical( + sprintf "output %s matches pattern %s", + $self->{genericsql}, $params{name2}); + } + } else { + if ($self->{genericsql} =~ /$params{name2}/) { + $self->add_nagios_ok( + sprintf "output %s matches pattern %s", + $self->{genericsql}, $params{name2}); + } else { + $self->add_nagios_critical( + sprintf "output %s does not match pattern %s", + $self->{genericsql}, $params{name2}); + } + } + } else { + $self->add_nagios( + # the first item in the list will trigger the threshold values + $self->check_thresholds($self->{genericsql}[0], 1, 5), + sprintf "%s: %s%s", + $params{name2} ? lc $params{name2} : lc $params{selectname}, + # float as float, integers as integers + join(" ", map { + (sprintf("%d", $_) eq $_) ? $_ : sprintf("%f", $_) + } @{$self->{genericsql}}), + $params{units} ? $params{units} : ""); + my $i = 0; + # workaround... getting the column names from the database would be nicer + my @names2_arr = split(/\s+/, $params{name2}); + foreach my $t (@{$self->{genericsql}}) { + $self->add_perfdata(sprintf "\'%s\'=%s%s;%s;%s", + $names2_arr[$i] ? lc $names2_arr[$i] : lc $params{selectname}, + # float as float, integers as integers + (sprintf("%d", $t) eq $t) ? $t : sprintf("%f", $t), + $params{units} ? $params{units} : "", + ($i == 0) ? $self->{warningrange} : "", + ($i == 0) ? $self->{criticalrange} : "" + ); + $i++; + } + } + } elsif ($params{mode} =~ /^my::([^:.]+)/) { + $self->{my}->nagios(%params); + $self->merge_nagios($self->{my}); + } + } +} + + +sub init_nagios { + my $self = shift; + no strict 'refs'; + if (! ref($self)) { + my $nagiosvar = $self."::nagios"; + my $nagioslevelvar = $self."::nagios_level"; + $$nagiosvar = { + messages => { + 0 => [], + 1 => [], + 2 => [], + 3 => [], + }, + perfdata => [], + }; + $$nagioslevelvar = $ERRORS{OK}, + } else { + $self->{nagios} = { + messages => { + 0 => [], + 1 => [], + 2 => [], + 3 => [], + }, + perfdata => [], + }; + $self->{nagios_level} = $ERRORS{OK}, + } +} + +sub check_thresholds { + my $self = shift; + my $value = shift; + my $defaultwarningrange = shift; + my $defaultcriticalrange = shift; + my $level = $ERRORS{OK}; + $self->{warningrange} = defined $self->{warningrange} ? + $self->{warningrange} : $defaultwarningrange; + $self->{criticalrange} = defined $self->{criticalrange} ? + $self->{criticalrange} : $defaultcriticalrange; + if ($self->{warningrange} !~ /:/ && $self->{criticalrange} !~ /:/) { + # warning = 10, critical = 20, warn if > 10, crit if > 20 + $level = $ERRORS{WARNING} if $value > $self->{warningrange}; + $level = $ERRORS{CRITICAL} if $value > $self->{criticalrange}; + } elsif ($self->{warningrange} =~ /([\d\.]+):/ && + $self->{criticalrange} =~ /([\d\.]+):/) { + # warning = 98:, critical = 95:, warn if < 98, crit if < 95 + $self->{warningrange} =~ /([\d\.]+):/; + $level = $ERRORS{WARNING} if $value < $1; + $self->{criticalrange} =~ /([\d\.]+):/; + $level = $ERRORS{CRITICAL} if $value < $1; + } + return $level; + # + # syntax error must be reported with returncode -1 + # +} + +sub add_nagios { + my $self = shift; + my $level = shift; + my $message = shift; + push(@{$self->{nagios}->{messages}->{$level}}, $message); + # recalc current level + foreach my $llevel qw(CRITICAL WARNING UNKNOWN OK) { + if (scalar(@{$self->{nagios}->{messages}->{$ERRORS{$llevel}}})) { + $self->{nagios_level} = $ERRORS{$llevel}; + } + } +} + +sub add_nagios_ok { + my $self = shift; + my $message = shift; + $self->add_nagios($ERRORS{OK}, $message); +} + +sub add_nagios_warning { + my $self = shift; + my $message = shift; + $self->add_nagios($ERRORS{WARNING}, $message); +} + +sub add_nagios_critical { + my $self = shift; + my $message = shift; + $self->add_nagios($ERRORS{CRITICAL}, $message); +} + +sub add_nagios_unknown { + my $self = shift; + my $message = shift; + $self->add_nagios($ERRORS{UNKNOWN}, $message); +} + +sub add_perfdata { + my $self = shift; + my $data = shift; + push(@{$self->{nagios}->{perfdata}}, $data); +} + +sub merge_nagios { + my $self = shift; + my $child = shift; + foreach my $level (0..3) { + foreach (@{$child->{nagios}->{messages}->{$level}}) { + $self->add_nagios($level, $_); + } + #push(@{$self->{nagios}->{messages}->{$level}}, + # @{$child->{nagios}->{messages}->{$level}}); + } + push(@{$self->{nagios}->{perfdata}}, @{$child->{nagios}->{perfdata}}); +} + +sub calculate_result { + my $self = shift; + my $labels = shift || {}; + my $multiline = 0; + map { + $self->{nagios_level} = $ERRORS{$_} if + (scalar(@{$self->{nagios}->{messages}->{$ERRORS{$_}}})); + } ("OK", "UNKNOWN", "WARNING", "CRITICAL"); + if ($ENV{NRPE_MULTILINESUPPORT} && + length join(" ", @{$self->{nagios}->{perfdata}}) > 200) { + $multiline = 1; + } + my $all_messages = join(($multiline ? "\n" : ", "), map { + join(($multiline ? "\n" : ", "), @{$self->{nagios}->{messages}->{$ERRORS{$_}}}) + } grep { + scalar(@{$self->{nagios}->{messages}->{$ERRORS{$_}}}) + } ("CRITICAL", "WARNING", "UNKNOWN", "OK")); + my $bad_messages = join(($multiline ? "\n" : ", "), map { + join(($multiline ? "\n" : ", "), @{$self->{nagios}->{messages}->{$ERRORS{$_}}}) + } grep { + scalar(@{$self->{nagios}->{messages}->{$ERRORS{$_}}}) + } ("CRITICAL", "WARNING", "UNKNOWN")); + my $all_messages_short = $bad_messages ? $bad_messages : 'no problems'; + my $all_messages_html = "<table style=\"border-collapse: collapse;\">". + join("", map { + my $level = $_; + join("", map { + sprintf "<tr valign=\"top\"><td class=\"service%s\">%s</td></tr>", + $level, $_; + } @{$self->{nagios}->{messages}->{$ERRORS{$_}}}); + } grep { + scalar(@{$self->{nagios}->{messages}->{$ERRORS{$_}}}) + } ("CRITICAL", "WARNING", "UNKNOWN", "OK")). + "</table>"; + if (exists $self->{identstring}) { + $self->{nagios_message} .= $self->{identstring}; + } + if ($self->{report} eq "long") { + $self->{nagios_message} .= $all_messages; + } elsif ($self->{report} eq "short") { + $self->{nagios_message} .= $all_messages_short; + } elsif ($self->{report} eq "html") { + $self->{nagios_message} .= $all_messages_short."\n".$all_messages_html; + } + if ($self->{labelformat} eq "pnp4nagios") { + $self->{perfdata} = join(" ", @{$self->{nagios}->{perfdata}}); + } else { + $self->{perfdata} = join(" ", map { + my $perfdata = $_; + if ($perfdata =~ /^(.*?)=(.*)/) { + my $label = $1; + my $data = $2; + if (exists $labels->{$label} && + exists $labels->{$label}->{$self->{labelformat}}) { + $labels->{$label}->{$self->{labelformat}}."=".$data; + } else { + $perfdata; + } + } else { + $perfdata; + } + } @{$self->{nagios}->{perfdata}}); + } +} + +sub set_global_db_thresholds { + my $self = shift; + my $params = shift; + my $warning = undef; + my $critical = undef; + return unless defined $params->{dbthresholds}; + $params->{name0} = $params->{dbthresholds}; + # :pluginmode :name :warning :critical + # mode empty + # + eval { + if ($self->{handle}->fetchrow_array(q{ + SELECT table_name + FROM information_schema.tables + WHERE table_schema = ? + AND table_name = 'CHECK_MYSQL_HEALTH_THRESHOLDS'; + }, $self->{database})) { # either --database... or information_schema + my @dbthresholds = $self->{handle}->fetchall_array(q{ + SELECT * FROM check_mysql_health_thresholds + }); + $params->{dbthresholds} = \@dbthresholds; + foreach (@dbthresholds) { + if (($_->[0] eq $params->{cmdlinemode}) && + (! defined $_->[1] || ! $_->[1])) { + ($warning, $critical) = ($_->[2], $_->[3]); + } + } + } + }; + if (! $@) { + if ($warning) { + $params->{warningrange} = $warning; + $self->trace("read warningthreshold %s from database", $warning); + } + if ($critical) { + $params->{criticalrange} = $critical; + $self->trace("read criticalthreshold %s from database", $critical); + } + } +} + +sub set_local_db_thresholds { + my $self = shift; + my %params = @_; + my $warning = undef; + my $critical = undef; + # :pluginmode :name :warning :critical + # mode name0 + # mode name2 + # mode name + # + # first: argument of --dbthresholds, it it exists + # second: --name2 + # third: --name + if (ref($params{dbthresholds}) eq 'ARRAY') { + my $marker; + foreach (@{$params{dbthresholds}}) { + if ($_->[0] eq $params{cmdlinemode}) { + if (defined $_->[1] && $params{name0} && $_->[1] eq $params{name0}) { + ($warning, $critical) = ($_->[2], $_->[3]); + $marker = $params{name0}; + last; + } elsif (defined $_->[1] && $params{name2} && $_->[1] eq $params{name2}) { + ($warning, $critical) = ($_->[2], $_->[3]); + $marker = $params{name2}; + last; + } elsif (defined $_->[1] && $params{name} && $_->[1] eq $params{name}) { + ($warning, $critical) = ($_->[2], $_->[3]); + $marker = $params{name}; + last; + } + } + } + if ($warning) { + $self->{warningrange} = $warning; + $self->trace("read warningthreshold %s for %s from database", + $marker, $warning); + } + if ($critical) { + $self->{criticalrange} = $critical; + $self->trace("read criticalthreshold %s for %s from database", + $marker, $critical); + } + } +} + +sub debug { + my $self = shift; + my $msg = shift; + if ($DBD::MySQL::Server::verbose) { + printf "%s %s\n", $msg, ref($self); + } +} + +sub dbconnect { + my $self = shift; + my %params = @_; + my $retval = undef; + $self->{tic} = Time::HiRes::time(); + $self->{handle} = DBD::MySQL::Server::Connection->new(%params); + if ($self->{handle}->{errstr}) { + if ($params{mode} =~ /^server::tnsping/ && + $self->{handle}->{errstr} =~ /ORA-01017/) { + $self->add_nagios($ERRORS{OK}, + sprintf "connection established to %s.", $self->{connect}); + $retval = undef; + } elsif ($self->{handle}->{errstr} eq "alarm\n") { + $self->add_nagios($ERRORS{CRITICAL}, + sprintf "connection could not be established within %d seconds", + $self->{timeout}); + } else { + $self->add_nagios($ERRORS{CRITICAL}, + sprintf "cannot connect to %s. %s", + $self->{database}, $self->{handle}->{errstr}); + $retval = undef; + } + } else { + $retval = $self->{handle}; + } + $self->{tac} = Time::HiRes::time(); + return $retval; +} + +sub trace { + my $self = shift; + my $format = shift; + $self->{trace} = -f "/tmp/check_mysql_health.trace" ? 1 : 0; + if ($self->{verbose}) { + printf("%s: ", scalar localtime); + printf($format, @_); + } + if ($self->{trace}) { + my $logfh = new IO::File; + $logfh->autoflush(1); + if ($logfh->open("/tmp/check_mysql_health.trace", "a")) { + $logfh->printf("%s: ", scalar localtime); + $logfh->printf($format, @_); + $logfh->printf("\n"); + $logfh->close(); + } + } +} + +sub DESTROY { + my $self = shift; + my $handle1 = "null"; + my $handle2 = "null"; + if (defined $self->{handle}) { + $handle1 = ref($self->{handle}); + if (defined $self->{handle}->{handle}) { + $handle2 = ref($self->{handle}->{handle}); + } + } + $self->trace(sprintf "DESTROY %s with handle %s %s", ref($self), $handle1, $handle2); + if (ref($self) eq "DBD::MySQL::Server") { + } + $self->trace(sprintf "DESTROY %s exit with handle %s %s", ref($self), $handle1, $handle2); + if (ref($self) eq "DBD::MySQL::Server") { + #printf "humpftata\n"; + } +} + +sub save_state { + my $self = shift; + my %params = @_; + my $extension = ""; + my $mode = $params{mode}; + if ($params{connect} && $params{connect} =~ /(\w+)\/(\w+)@(\w+)/) { + $params{connect} = $3; + } elsif ($params{connect}) { + # just to be sure + $params{connect} =~ s/\//_/g; + } + if ($^O =~ /MSWin/) { + $mode =~ s/::/_/g; + $params{statefilesdir} = $self->system_vartmpdir(); + } + if (! -d $params{statefilesdir}) { + eval { + use File::Path; + mkpath $params{statefilesdir}; + }; + } + if ($@ || ! -w $params{statefilesdir}) { + $self->add_nagios($ERRORS{CRITICAL}, + sprintf "statefilesdir %s does not exist or is not writable\n", + $params{statefilesdir}); + return; + } + my $statefile = sprintf "%s_%s", $params{hostname}, $mode; + $extension .= $params{differenciator} ? "_".$params{differenciator} : ""; + $extension .= $params{socket} ? "_".$params{socket} : ""; + $extension .= $params{port} ? "_".$params{port} : ""; + $extension .= $params{database} ? "_".$params{database} : ""; + $extension .= $params{tablespace} ? "_".$params{tablespace} : ""; + $extension .= $params{datafile} ? "_".$params{datafile} : ""; + $extension .= $params{name} ? "_".$params{name} : ""; + $extension =~ s/\//_/g; + $extension =~ s/\(/_/g; + $extension =~ s/\)/_/g; + $extension =~ s/\*/_/g; + $extension =~ s/\s/_/g; + $statefile .= $extension; + $statefile = lc $statefile; + $statefile = sprintf "%s/%s", $params{statefilesdir}, $statefile; + if (open(STATE, ">$statefile")) { + if ((ref($params{save}) eq "HASH") && exists $params{save}->{timestamp}) { + $params{save}->{localtime} = scalar localtime $params{save}->{timestamp}; + } + printf STATE Data::Dumper::Dumper($params{save}); + close STATE; + } else { + $self->add_nagios($ERRORS{CRITICAL}, + sprintf "statefile %s is not writable", $statefile); + } + $self->debug(sprintf "saved %s to %s", + Data::Dumper::Dumper($params{save}), $statefile); +} + +sub load_state { + my $self = shift; + my %params = @_; + my $extension = ""; + my $mode = $params{mode}; + if ($params{connect} && $params{connect} =~ /(\w+)\/(\w+)@(\w+)/) { + $params{connect} = $3; + } elsif ($params{connect}) { + # just to be sure + $params{connect} =~ s/\//_/g; + } + if ($^O =~ /MSWin/) { + $mode =~ s/::/_/g; + $params{statefilesdir} = $self->system_vartmpdir(); + } + my $statefile = sprintf "%s_%s", $params{hostname}, $mode; + $extension .= $params{differenciator} ? "_".$params{differenciator} : ""; + $extension .= $params{socket} ? "_".$params{socket} : ""; + $extension .= $params{port} ? "_".$params{port} : ""; + $extension .= $params{database} ? "_".$params{database} : ""; + $extension .= $params{tablespace} ? "_".$params{tablespace} : ""; + $extension .= $params{datafile} ? "_".$params{datafile} : ""; + $extension .= $params{name} ? "_".$params{name} : ""; + $extension =~ s/\//_/g; + $extension =~ s/\(/_/g; + $extension =~ s/\)/_/g; + $extension =~ s/\*/_/g; + $extension =~ s/\s/_/g; + $statefile .= $extension; + $statefile = lc $statefile; + $statefile = sprintf "%s/%s", $params{statefilesdir}, $statefile; + if ( -f $statefile) { + our $VAR1; + eval { + require $statefile; + }; + if($@) { + $self->add_nagios($ERRORS{CRITICAL}, + sprintf "statefile %s is corrupt", $statefile); + } + $self->debug(sprintf "load %s", Data::Dumper::Dumper($VAR1)); + return $VAR1; + } else { + return undef; + } +} + +sub valdiff { + my $self = shift; + my $pparams = shift; + my %params = %{$pparams}; + my @keys = @_; + my $now = time; + my $last_values = $self->load_state(%params) || eval { + my $empty_events = {}; + foreach (@keys) { + $empty_events->{$_} = 0; + } + $empty_events->{timestamp} = 0; + if ($params{lookback}) { + $empty_events->{lookback_history} = {}; + } + $empty_events; + }; + foreach (@keys) { + if ($params{lookback}) { + # find a last_value in the history which fits lookback best + # and overwrite $last_values->{$_} with historic data + if (exists $last_values->{lookback_history}->{$_}) { + foreach my $date (sort {$a <=> $b} keys %{$last_values->{lookback_history}->{$_}}) { + if ($date >= ($now - $params{lookback})) { + $last_values->{$_} = $last_values->{lookback_history}->{$_}->{$date}; + $last_values->{timestamp} = $date; + last; + } else { + delete $last_values->{lookback_history}->{$_}->{$date}; + } + } + } + } + $last_values->{$_} = 0 if ! exists $last_values->{$_}; + if ($self->{$_} >= $last_values->{$_}) { + $self->{'delta_'.$_} = $self->{$_} - $last_values->{$_}; + } else { + # vermutlich db restart und zaehler alle auf null + $self->{'delta_'.$_} = $self->{$_}; + } + $self->debug(sprintf "delta_%s %f", $_, $self->{'delta_'.$_}); + } + $self->{'delta_timestamp'} = $now - $last_values->{timestamp}; + $params{save} = eval { + my $empty_events = {}; + foreach (@keys) { + $empty_events->{$_} = $self->{$_}; + } + $empty_events->{timestamp} = $now; + if ($params{lookback}) { + $empty_events->{lookback_history} = $last_values->{lookback_history}; + foreach (@keys) { + $empty_events->{lookback_history}->{$_}->{$now} = $self->{$_}; + } + } + $empty_events; + }; + $self->save_state(%params); +} + +sub requires_version { + my $self = shift; + my $version = shift; + my @instances = DBD::MySQL::Server::return_servers(); + my $instversion = $instances[0]->{version}; + if (! $self->version_is_minimum($version)) { + $self->add_nagios($ERRORS{UNKNOWN}, + sprintf "not implemented/possible for MySQL release %s", $instversion); + } +} + +sub version_is_minimum { + # the current version is newer or equal + my $self = shift; + my $version = shift; + my $newer = 1; + my @instances = DBD::MySQL::Server::return_servers(); + my @v1 = map { $_ eq "x" ? 0 : $_ } split(/\./, $version); + my @v2 = split(/\./, $instances[0]->{version}); + if (scalar(@v1) > scalar(@v2)) { + push(@v2, (0) x (scalar(@v1) - scalar(@v2))); + } elsif (scalar(@v2) > scalar(@v1)) { + push(@v1, (0) x (scalar(@v2) - scalar(@v1))); + } + foreach my $pos (0..$#v1) { + if ($v2[$pos] > $v1[$pos]) { + $newer = 1; + last; + } elsif ($v2[$pos] < $v1[$pos]) { + $newer = 0; + last; + } + } + #printf STDERR "check if %s os minimum %s\n", join(".", @v2), join(".", @v1); + return $newer; +} + +sub instance_thread { + my $self = shift; + my @instances = DBD::MySQL::Server::return_servers(); + return $instances[0]->{thread}; +} + +sub windows_server { + my $self = shift; + my @instances = DBD::MySQL::Server::return_servers(); + if ($instances[0]->{os} =~ /Win/i) { + return 1; + } else { + return 0; + } +} + +sub system_vartmpdir { + my $self = shift; + if ($^O =~ /MSWin/) { + return $self->system_tmpdir(); + } else { + return "/var/tmp/check_mysql_health"; + } +} + +sub system_oldvartmpdir { + my $self = shift; + return "/tmp"; +} + +sub system_tmpdir { + my $self = shift; + if ($^O =~ /MSWin/) { + return $ENV{TEMP} if defined $ENV{TEMP}; + return $ENV{TMP} if defined $ENV{TMP}; + return File::Spec->catfile($ENV{windir}, 'Temp') + if defined $ENV{windir}; + return 'C:\Temp'; + } else { + return "/tmp"; + } +} + + +package DBD::MySQL::Server::Connection; + +use strict; + +our @ISA = qw(DBD::MySQL::Server); + + +sub new { + my $class = shift; + my %params = @_; + my $self = { + mode => $params{mode}, + timeout => $params{timeout}, + access => $params{method} || "dbi", + hostname => $params{hostname}, + database => $params{database} || "information_schema", + port => $params{port}, + socket => $params{socket}, + username => $params{username}, + password => $params{password}, + handle => undef, + }; + bless $self, $class; + if ($params{method} eq "dbi") { + bless $self, "DBD::MySQL::Server::Connection::Dbi"; + } elsif ($params{method} eq "mysql") { + bless $self, "DBD::MySQL::Server::Connection::Mysql"; + } elsif ($params{method} eq "sqlrelay") { + bless $self, "DBD::MySQL::Server::Connection::Sqlrelay"; + } + $self->init(%params); + return $self; +} + + +package DBD::MySQL::Server::Connection::Dbi; + +use strict; +use Net::Ping; + +our @ISA = qw(DBD::MySQL::Server::Connection); + + +sub init { + my $self = shift; + my %params = @_; + my $retval = undef; + if ($self->{mode} =~ /^server::tnsping/) { + if (! $self->{connect}) { + $self->{errstr} = "Please specify a database"; + } else { + $self->{sid} = $self->{connect}; + $self->{username} ||= time; # prefer an existing user + $self->{password} = time; + } + } else { + if (($self->{hostname} ne 'localhost') && (! $self->{username} || ! $self->{password})) { + $self->{errstr} = "Please specify hostname, username and password"; + return undef; + } + $self->{dsn} = "DBI:mysql:"; + $self->{dsn} .= sprintf "database=%s", $self->{database}; + $self->{dsn} .= sprintf ";host=%s", $self->{hostname}; + $self->{dsn} .= sprintf ";port=%s", $self->{port} + unless $self->{socket} || $self->{hostname} eq 'localhost'; + $self->{dsn} .= sprintf ";mysql_socket=%s", $self->{socket} + if $self->{socket}; + } + if (! exists $self->{errstr}) { + eval { + require DBI; + use POSIX ':signal_h'; + local $SIG{'ALRM'} = sub { + die "alarm\n"; + }; + my $mask = POSIX::SigSet->new( SIGALRM ); + my $action = POSIX::SigAction->new( + sub { die "alarm\n" ; }, $mask); + my $oldaction = POSIX::SigAction->new(); + sigaction(SIGALRM ,$action ,$oldaction ); + alarm($self->{timeout} - 1); # 1 second before the global unknown timeout + if ($self->{handle} = DBI->connect( + $self->{dsn}, + $self->{username}, + $self->{password}, + { RaiseError => 0, AutoCommit => 0, PrintError => 0 })) { +# $self->{handle}->do(q{ +# ALTER SESSION SET NLS_NUMERIC_CHARACTERS=".," }); + $retval = $self; + } else { + $self->{errstr} = DBI::errstr(); + } + }; + if ($@) { + $self->{errstr} = $@; + $retval = undef; + } + } + $self->{tac} = Time::HiRes::time(); + return $retval; +} + +sub selectrow_hashref { + my $self = shift; + my $sql = shift; + my @arguments = @_; + my $sth = undef; + my $hashref = undef; + eval { + $self->trace(sprintf "SQL:\n%s\nARGS:\n%s\n", + $sql, Data::Dumper::Dumper(\@arguments)); + # helm auf! jetzt wirds dreckig. + if ($sql =~ /^\s*SHOW/) { + $hashref = $self->{handle}->selectrow_hashref($sql); + } else { + $sth = $self->{handle}->prepare($sql); + if (scalar(@arguments)) { + $sth->execute(@arguments); + } else { + $sth->execute(); + } + $hashref = $sth->selectrow_hashref(); + } + $self->trace(sprintf "RESULT:\n%s\n", + Data::Dumper::Dumper($hashref)); + }; + if ($@) { + $self->debug(sprintf "bumm %s", $@); + } + if (-f "/tmp/check_mysql_health_simulation/".$self->{mode}) { + my $simulation = do { local (@ARGV, $/) = + "/tmp/check_mysql_health_simulation/".$self->{mode}; <> }; + # keine lust auf den scheiss + } + return $hashref; +} + +sub fetchrow_array { + my $self = shift; + my $sql = shift; + my @arguments = @_; + my $sth = undef; + my @row = (); + eval { + $self->trace(sprintf "SQL:\n%s\nARGS:\n%s\n", + $sql, Data::Dumper::Dumper(\@arguments)); + $sth = $self->{handle}->prepare($sql); + if (scalar(@arguments)) { + $sth->execute(@arguments); + } else { + $sth->execute(); + } + @row = $sth->fetchrow_array(); + $self->trace(sprintf "RESULT:\n%s\n", + Data::Dumper::Dumper(\@row)); + }; + if ($@) { + $self->debug(sprintf "bumm %s", $@); + } + if (-f "/tmp/check_mysql_health_simulation/".$self->{mode}) { + my $simulation = do { local (@ARGV, $/) = + "/tmp/check_mysql_health_simulation/".$self->{mode}; <> }; + @row = split(/\s+/, (split(/\n/, $simulation))[0]); + } + return $row[0] unless wantarray; + return @row; +} + +sub fetchall_array { + my $self = shift; + my $sql = shift; + my @arguments = @_; + my $sth = undef; + my $rows = undef; + eval { + $self->trace(sprintf "SQL:\n%s\nARGS:\n%s\n", + $sql, Data::Dumper::Dumper(\@arguments)); + $sth = $self->{handle}->prepare($sql); + if (scalar(@arguments)) { + $sth->execute(@arguments); + } else { + $sth->execute(); + } + $rows = $sth->fetchall_arrayref(); + $self->trace(sprintf "RESULT:\n%s\n", + Data::Dumper::Dumper($rows)); + }; + if ($@) { + printf STDERR "bumm %s\n", $@; + } + if (-f "/tmp/check_mysql_health_simulation/".$self->{mode}) { + my $simulation = do { local (@ARGV, $/) = + "/tmp/check_mysql_health_simulation/".$self->{mode}; <> }; + @{$rows} = map { [ split(/\s+/, $_) ] } split(/\n/, $simulation); + } + return @{$rows}; +} + +sub func { + my $self = shift; + $self->{handle}->func(@_); +} + + +sub execute { + my $self = shift; + my $sql = shift; + eval { + my $sth = $self->{handle}->prepare($sql); + $sth->execute(); + }; + if ($@) { + printf STDERR "bumm %s\n", $@; + } +} + +sub errstr { + my $self = shift; + return $self->{errstr}; +} + +sub DESTROY { + my $self = shift; + $self->trace(sprintf "disconnecting DBD %s", + $self->{handle} ? "with handle" : "without handle"); + $self->{handle}->disconnect() if $self->{handle}; +} + +package DBD::MySQL::Server::Connection::Mysql; + +use strict; +use File::Temp qw/tempfile/; + +our @ISA = qw(DBD::MySQL::Server::Connection); + + +sub init { + my $self = shift; + my %params = @_; + my $retval = undef; + $self->{loginstring} = "traditional"; + ($self->{sql_commandfile_handle}, $self->{sql_commandfile}) = + tempfile($self->{mode}."XXXXX", SUFFIX => ".sql", + DIR => $self->system_tmpdir() ); + close $self->{sql_commandfile_handle}; + ($self->{sql_resultfile_handle}, $self->{sql_resultfile}) = + tempfile($self->{mode}."XXXXX", SUFFIX => ".out", + DIR => $self->system_tmpdir() ); + close $self->{sql_resultfile_handle}; + if ($self->{mode} =~ /^server::tnsping/) { + if (! $self->{connect}) { + $self->{errstr} = "Please specify a database"; + } else { + $self->{sid} = $self->{connect}; + $self->{username} ||= time; # prefer an existing user + $self->{password} = time; + } + } else { + if (! $self->{username} || ! $self->{password}) { + $self->{errstr} = "Please specify database, username and password"; + return undef; + } elsif (! (($self->{hostname} && $self->{port}) || $self->{socket})) { + $self->{errstr} = "Please specify hostname and port or socket"; + return undef; + } + } + if (! exists $self->{errstr}) { + eval { + my $mysql = '/'.'usr'.'/'.'bin'.'/'.'mysql'; + if (! -x $mysql) { + die "nomysql\n"; + } + if ($self->{loginstring} eq "traditional") { + $self->{sqlplus} = sprintf "%s ", $mysql; + $self->{sqlplus} .= sprintf "--batch --raw --skip-column-names "; + $self->{sqlplus} .= sprintf "--database=%s ", $self->{database}; + $self->{sqlplus} .= sprintf "--host=%s ", $self->{hostname}; + $self->{sqlplus} .= sprintf "--port=%s ", $self->{port} + unless $self->{socket} || $self->{hostname} eq "localhost"; + $self->{sqlplus} .= sprintf "--socket=%s ", $self->{socket} + if $self->{socket}; + $self->{sqlplus} .= sprintf "--user=%s --password=%s < %s > %s", + $self->{username}, $self->{password}, + $self->{sql_commandfile}, $self->{sql_resultfile}; + } + + use POSIX ':signal_h'; + local $SIG{'ALRM'} = sub { + die "alarm\n"; + }; + my $mask = POSIX::SigSet->new( SIGALRM ); + my $action = POSIX::SigAction->new( + sub { die "alarm\n" ; }, $mask); + my $oldaction = POSIX::SigAction->new(); + sigaction(SIGALRM ,$action ,$oldaction ); + alarm($self->{timeout} - 1); # 1 second before the global unknown timeout + + my $answer = $self->fetchrow_array( + q{ SELECT 42 FROM dual}); + die unless defined $answer and $answer == 42; + $retval = $self; + }; + if ($@) { + $self->{errstr} = $@; + $self->{errstr} =~ s/at $0 .*//g; + chomp $self->{errstr}; + $retval = undef; + } + } + $self->{tac} = Time::HiRes::time(); + return $retval; +} + +sub selectrow_hashref { + my $self = shift; + my $sql = shift; + my @arguments = @_; + my $sth = undef; + my $hashref = undef; + foreach (@arguments) { + # replace the ? by the parameters + if (/^\d+$/) { + $sql =~ s/\?/$_/; + } else { + $sql =~ s/\?/'$_'/; + } + } + if ($sql =~ /^\s*SHOW/) { + $sql .= '\G'; # http://dev.mysql.com/doc/refman/5.1/de/show-slave-status.html + } + $self->trace(sprintf "SQL (? resolved):\n%s\nARGS:\n%s\n", + $sql, Data::Dumper::Dumper(\@arguments)); + $self->create_commandfile($sql); + my $exit_output = `$self->{sqlplus}`; + if ($?) { + printf STDERR "fetchrow_array exit bumm \n"; + my $output = do { local (@ARGV, $/) = $self->{sql_resultfile}; <> }; + my @oerrs = map { + /((ERROR \d+).*)/ ? $1 : (); + } split(/\n/, $output); + $self->{errstr} = join(" ", @oerrs); + } else { + my $output = do { local (@ARGV, $/) = $self->{sql_resultfile}; <> }; + if ($sql =~ /^\s*SHOW/) { + map { + if (/^\s*([\w_]+):\s*(.*)/) { + $hashref->{$1} = $2; + } + } split(/\n/, $output); + } else { + # i dont mess around here and you shouldn't either + } + $self->trace(sprintf "RESULT:\n%s\n", + Data::Dumper::Dumper($hashref)); + } + unlink $self->{sql_commandfile}; + unlink $self->{sql_resultfile}; + return $hashref; +} + +sub fetchrow_array { + my $self = shift; + my $sql = shift; + my @arguments = @_; + my $sth = undef; + my @row = (); + foreach (@arguments) { + # replace the ? by the parameters + if (/^\d+$/) { + $sql =~ s/\?/$_/; + } else { + $sql =~ s/\?/'$_'/; + } + } + $self->trace(sprintf "SQL (? resolved):\n%s\nARGS:\n%s\n", + $sql, Data::Dumper::Dumper(\@arguments)); + $self->create_commandfile($sql); + my $exit_output = `$self->{sqlplus}`; + if ($?) { + printf STDERR "fetchrow_array exit bumm \n"; + my $output = do { local (@ARGV, $/) = $self->{sql_resultfile}; <> }; + my @oerrs = map { + /((ERROR \d+).*)/ ? $1 : (); + } split(/\n/, $output); + $self->{errstr} = join(" ", @oerrs); + } else { + my $output = do { local (@ARGV, $/) = $self->{sql_resultfile}; <> }; + @row = map { convert($_) } + map { s/^\s+([\.\d]+)$/$1/g; $_ } # strip leading space from numbers + map { s/\s+$//g; $_ } # strip trailing space + split(/\t/, (split(/\n/, $output))[0]); + $self->trace(sprintf "RESULT:\n%s\n", + Data::Dumper::Dumper(\@row)); + } + if ($@) { + $self->debug(sprintf "bumm %s", $@); + } + unlink $self->{sql_commandfile}; + unlink $self->{sql_resultfile}; + return $row[0] unless wantarray; + return @row; +} + +sub fetchall_array { + my $self = shift; + my $sql = shift; + my @arguments = @_; + my $sth = undef; + my $rows = undef; + foreach (@arguments) { + # replace the ? by the parameters + if (/^\d+$/) { + $sql =~ s/\?/$_/; + } else { + $sql =~ s/\?/'$_'/; + } + } + $self->trace(sprintf "SQL (? resolved):\n%s\nARGS:\n%s\n", + $sql, Data::Dumper::Dumper(\@arguments)); + $self->create_commandfile($sql); + my $exit_output = `$self->{sqlplus}`; + if ($?) { + printf STDERR "fetchrow_array exit bumm %s\n", $exit_output; + my $output = do { local (@ARGV, $/) = $self->{sql_resultfile}; <> }; + my @oerrs = map { + /((ERROR \d+).*)/ ? $1 : (); + } split(/\n/, $output); + $self->{errstr} = join(" ", @oerrs); + } else { + my $output = do { local (@ARGV, $/) = $self->{sql_resultfile}; <> }; + my @rows = map { [ + map { convert($_) } + map { s/^\s+([\.\d]+)$/$1/g; $_ } + map { s/\s+$//g; $_ } + split /\t/ + ] } grep { ! /^\d+ rows selected/ } + grep { ! /^Elapsed: / } + grep { ! /^\s*$/ } split(/\n/, $output); + $rows = \@rows; + $self->trace(sprintf "RESULT:\n%s\n", + Data::Dumper::Dumper($rows)); + } + if ($@) { + $self->debug(sprintf "bumm %s", $@); + } + unlink $self->{sql_commandfile}; + unlink $self->{sql_resultfile}; + return @{$rows}; +} + +sub func { + my $self = shift; + my $function = shift; + $self->{handle}->func(@_); +} + +sub convert { + my $n = shift; + # mostly used to convert numbers in scientific notation + if ($n =~ /^\s*\d+\s*$/) { + return $n; + } elsif ($n =~ /^\s*([-+]?)(\d*[\.,]*\d*)[eE]{1}([-+]?)(\d+)\s*$/) { + my ($vor, $num, $sign, $exp) = ($1, $2, $3, $4); + $n =~ s/E/e/g; + $n =~ s/,/\./g; + $num =~ s/,/\./g; + my $sig = $sign eq '-' ? "." . ($exp - 1 + length $num) : ''; + my $dec = sprintf "%${sig}f", $n; + $dec =~ s/\.[0]+$//g; + return $dec; + } elsif ($n =~ /^\s*([-+]?)(\d+)[\.,]*(\d*)\s*$/) { + return $1.$2.".".$3; + } elsif ($n =~ /^\s*(.*?)\s*$/) { + return $1; + } else { + return $n; + } +} + + +sub execute { + my $self = shift; + my $sql = shift; + eval { + my $sth = $self->{handle}->prepare($sql); + $sth->execute(); + }; + if ($@) { + printf STDERR "bumm %s\n", $@; + } +} + +sub errstr { + my $self = shift; + return $self->{errstr}; +} + +sub DESTROY { + my $self = shift; + $self->trace("try to clean up command and result files"); + unlink $self->{sql_commandfile} if -f $self->{sql_commandfile}; + unlink $self->{sql_resultfile} if -f $self->{sql_resultfile}; +} + +sub create_commandfile { + my $self = shift; + my $sql = shift; + open CMDCMD, "> $self->{sql_commandfile}"; + printf CMDCMD "%s\n", $sql; + close CMDCMD; +} + + +package DBD::MySQL::Server::Connection::Sqlrelay; + +use strict; +use Net::Ping; + +our @ISA = qw(DBD::MySQL::Server::Connection); + + +sub init { + my $self = shift; + my %params = @_; + my $retval = undef; + if ($self->{mode} =~ /^server::tnsping/) { + if (! $self->{connect}) { + $self->{errstr} = "Please specify a database"; + } else { + if ($self->{connect} =~ /([\.\w]+):(\d+)/) { + $self->{host} = $1; + $self->{port} = $2; + $self->{socket} = ""; + } elsif ($self->{connect} =~ /([\.\w]+):([\w\/]+)/) { + $self->{host} = $1; + $self->{socket} = $2; + $self->{port} = ""; + } + } + } else { + if (! $self->{hostname} || ! $self->{username} || ! $self->{password}) { + if ($self->{hostname} && $self->{hostname} =~ /(\w+)\/(\w+)@([\.\w]+):(\d+)/) { + $self->{username} = $1; + $self->{password} = $2; + $self->{hostname} = $3; + $self->{port} = $4; + $self->{socket} = ""; + } elsif ($self->{hostname} && $self->{hostname} =~ /(\w+)\/(\w+)@([\.\w]+):([\w\/]+)/) { + $self->{username} = $1; + $self->{password} = $2; + $self->{hostname} = $3; + $self->{socket} = $4; + $self->{port} = ""; + } else { + $self->{errstr} = "Please specify database, username and password"; + return undef; + } + } else { + if ($self->{hostname} =~ /([\.\w]+):(\d+)/) { + $self->{hostname} = $1; + $self->{port} = $2; + $self->{socket} = ""; + } elsif ($self->{hostname} =~ /([\.\w]+):([\w\/]+)/) { + $self->{hostname} = $1; + $self->{socket} = $2; + $self->{port} = ""; + } else { + $self->{errstr} = "Please specify hostname, username, password and port/socket"; + return undef; + } + } + } + if (! exists $self->{errstr}) { + eval { + require DBI; + use POSIX ':signal_h'; + local $SIG{'ALRM'} = sub { + die "alarm\n"; + }; + my $mask = POSIX::SigSet->new( SIGALRM ); + my $action = POSIX::SigAction->new( + sub { die "alarm\n" ; }, $mask); + my $oldaction = POSIX::SigAction->new(); + sigaction(SIGALRM ,$action ,$oldaction ); + alarm($self->{timeout} - 1); # 1 second before the global unknown timeout + if ($self->{handle} = DBI->connect( + sprintf("DBI:SQLRelay:host=%s;port=%d;socket=%s", + $self->{hostname}, $self->{port}, $self->{socket}), + $self->{username}, + $self->{password}, + { RaiseError => 1, AutoCommit => 0, PrintError => 1 })) { + $retval = $self; + if ($self->{mode} =~ /^server::tnsping/ && $self->{handle}->ping()) { + # database connected. fake a "unknown user" + $self->{errstr} = "ORA-01017"; + } + } else { + $self->{errstr} = DBI::errstr(); + } + }; + if ($@) { + $self->{errstr} = $@; + $self->{errstr} =~ s/at [\w\/\.]+ line \d+.*//g; + $retval = undef; + } + } + $self->{tac} = Time::HiRes::time(); + return $retval; +} + +sub fetchrow_array { + my $self = shift; + my $sql = shift; + my @arguments = @_; + my $sth = undef; + my @row = (); + $self->trace(sprintf "fetchrow_array: %s", $sql); + eval { + $sth = $self->{handle}->prepare($sql); + if (scalar(@arguments)) { + $sth->execute(@arguments); + } else { + $sth->execute(); + } + @row = $sth->fetchrow_array(); + }; + if ($@) { + $self->debug(sprintf "bumm %s", $@); + } + if (-f "/tmp/check_mysql_health_simulation/".$self->{mode}) { + my $simulation = do { local (@ARGV, $/) = + "/tmp/check_mysql_health_simulation/".$self->{mode}; <> }; + @row = split(/\s+/, (split(/\n/, $simulation))[0]); + } + return $row[0] unless wantarray; + return @row; +} + +sub fetchall_array { + my $self = shift; + my $sql = shift; + my @arguments = @_; + my $sth = undef; + my $rows = undef; + $self->trace(sprintf "fetchall_array: %s", $sql); + eval { + $sth = $self->{handle}->prepare($sql); + if (scalar(@arguments)) { + $sth->execute(@arguments); + } else { + $sth->execute(); + } + $rows = $sth->fetchall_arrayref(); + }; + if ($@) { + printf STDERR "bumm %s\n", $@; + } + if (-f "/tmp/check_mysql_health_simulation/".$self->{mode}) { + my $simulation = do { local (@ARGV, $/) = + "/tmp/check_mysql_health_simulation/".$self->{mode}; <> }; + @{$rows} = map { [ split(/\s+/, $_) ] } split(/\n/, $simulation); + } + return @{$rows}; +} + +sub func { + my $self = shift; + $self->{handle}->func(@_); +} + +sub execute { + my $self = shift; + my $sql = shift; + eval { + my $sth = $self->{handle}->prepare($sql); + $sth->execute(); + }; + if ($@) { + printf STDERR "bumm %s\n", $@; + } +} + +sub DESTROY { + my $self = shift; + #$self->trace(sprintf "disconnecting DBD %s", + # $self->{handle} ? "with handle" : "without handle"); + #$self->{handle}->disconnect() if $self->{handle}; +} + + + + +package DBD::MySQL::Cluster; + +use strict; +use Time::HiRes; +use IO::File; +use Data::Dumper; + + +{ + our $verbose = 0; + our $scream = 0; # scream if something is not implemented + our $access = "dbi"; # how do we access the database. + our $my_modules_dyn_dir = ""; # where we look for self-written extensions + + my @clusters = (); + my $initerrors = undef; + + sub add_cluster { + push(@clusters, shift); + } + + sub return_clusters { + return @clusters; + } + + sub return_first_cluster() { + return $clusters[0]; + } + +} + +sub new { + my $class = shift; + my %params = @_; + my $self = { + hostname => $params{hostname}, + port => $params{port}, + username => $params{username}, + password => $params{password}, + timeout => $params{timeout}, + warningrange => $params{warningrange}, + criticalrange => $params{criticalrange}, + version => 'unknown', + nodes => [], + ndbd_nodes => 0, + ndb_mgmd_nodes => 0, + mysqld_nodes => 0, + }; + bless $self, $class; + $self->init_nagios(); + if ($self->connect(%params)) { + DBD::MySQL::Cluster::add_cluster($self); + $self->init(%params); + } + return $self; +} + +sub init { + my $self = shift; + my %params = @_; + if ($self->{show}) { + my $type = undef; + foreach (split /\n/, $self->{show}) { + if (/\[(\w+)\((\w+)\)\]\s+(\d+) node/) { + $type = uc $2; + } elsif (/id=(\d+)(.*)/) { + push(@{$self->{nodes}}, DBD::MySQL::Cluster::Node->new( + type => $type, + id => $1, + status => $2, + )); + } + } + } else { + } + if ($params{mode} =~ /^cluster::ndbdrunning/) { + foreach my $node (@{$self->{nodes}}) { + $node->{type} eq "NDB" && $node->{status} eq "running" && $self->{ndbd_nodes}++; + $node->{type} eq "MGM" && $node->{status} eq "running" && $self->{ndb_mgmd_nodes}++; + $node->{type} eq "API" && $node->{status} eq "running" && $self->{mysqld_nodes}++; + } + } else { + printf "broken mode %s\n", $params{mode}; + } +} + +sub dump { + my $self = shift; + my $message = shift || ""; + printf "%s %s\n", $message, Data::Dumper::Dumper($self); +} + +sub nagios { + my $self = shift; + my %params = @_; + my $dead_ndb = 0; + my $dead_api = 0; + if (! $self->{nagios_level}) { + if ($params{mode} =~ /^cluster::ndbdrunning/) { + foreach my $node (grep { $_->{type} eq "NDB"} @{$self->{nodes}}) { + next if $params{selectname} && $params{selectname} ne $_->{id}; + if (! $node->{connected}) { + $self->add_nagios_critical( + sprintf "ndb node %d is not connected", $node->{id}); + $dead_ndb++; + } + } + foreach my $node (grep { $_->{type} eq "API"} @{$self->{nodes}}) { + next if $params{selectname} && $params{selectname} ne $_->{id}; + if (! $node->{connected}) { + $self->add_nagios_critical( + sprintf "api node %d is not connected", $node->{id}); + $dead_api++; + } + } + if (! $dead_ndb) { + $self->add_nagios_ok("all ndb nodes are connected"); + } + if (! $dead_api) { + $self->add_nagios_ok("all api nodes are connected"); + } + } + } + $self->add_perfdata(sprintf "ndbd_nodes=%d ndb_mgmd_nodes=%d mysqld_nodes=%d", + $self->{ndbd_nodes}, $self->{ndb_mgmd_nodes}, $self->{mysqld_nodes}); +} + + +sub init_nagios { + my $self = shift; + no strict 'refs'; + if (! ref($self)) { + my $nagiosvar = $self."::nagios"; + my $nagioslevelvar = $self."::nagios_level"; + $$nagiosvar = { + messages => { + 0 => [], + 1 => [], + 2 => [], + 3 => [], + }, + perfdata => [], + }; + $$nagioslevelvar = $ERRORS{OK}, + } else { + $self->{nagios} = { + messages => { + 0 => [], + 1 => [], + 2 => [], + 3 => [], + }, + perfdata => [], + }; + $self->{nagios_level} = $ERRORS{OK}, + } +} + +sub check_thresholds { + my $self = shift; + my $value = shift; + my $defaultwarningrange = shift; + my $defaultcriticalrange = shift; + my $level = $ERRORS{OK}; + $self->{warningrange} = $self->{warningrange} ? + $self->{warningrange} : $defaultwarningrange; + $self->{criticalrange} = $self->{criticalrange} ? + $self->{criticalrange} : $defaultcriticalrange; + if ($self->{warningrange} !~ /:/ && $self->{criticalrange} !~ /:/) { + # warning = 10, critical = 20, warn if > 10, crit if > 20 + $level = $ERRORS{WARNING} if $value > $self->{warningrange}; + $level = $ERRORS{CRITICAL} if $value > $self->{criticalrange}; + } elsif ($self->{warningrange} =~ /([\d\.]+):/ && + $self->{criticalrange} =~ /([\d\.]+):/) { + # warning = 98:, critical = 95:, warn if < 98, crit if < 95 + $self->{warningrange} =~ /([\d\.]+):/; + $level = $ERRORS{WARNING} if $value < $1; + $self->{criticalrange} =~ /([\d\.]+):/; + $level = $ERRORS{CRITICAL} if $value < $1; + } + return $level; + # + # syntax error must be reported with returncode -1 + # +} + +sub add_nagios { + my $self = shift; + my $level = shift; + my $message = shift; + push(@{$self->{nagios}->{messages}->{$level}}, $message); + # recalc current level + foreach my $llevel qw(CRITICAL WARNING UNKNOWN OK) { + if (scalar(@{$self->{nagios}->{messages}->{$ERRORS{$llevel}}})) { + $self->{nagios_level} = $ERRORS{$llevel}; + } + } +} + +sub add_nagios_ok { + my $self = shift; + my $message = shift; + $self->add_nagios($ERRORS{OK}, $message); +} + +sub add_nagios_warning { + my $self = shift; + my $message = shift; + $self->add_nagios($ERRORS{WARNING}, $message); +} + +sub add_nagios_critical { + my $self = shift; + my $message = shift; + $self->add_nagios($ERRORS{CRITICAL}, $message); +} + +sub add_nagios_unknown { + my $self = shift; + my $message = shift; + $self->add_nagios($ERRORS{UNKNOWN}, $message); +} + +sub add_perfdata { + my $self = shift; + my $data = shift; + push(@{$self->{nagios}->{perfdata}}, $data); +} + +sub merge_nagios { + my $self = shift; + my $child = shift; + foreach my $level (0..3) { + foreach (@{$child->{nagios}->{messages}->{$level}}) { + $self->add_nagios($level, $_); + } + #push(@{$self->{nagios}->{messages}->{$level}}, + # @{$child->{nagios}->{messages}->{$level}}); + } + push(@{$self->{nagios}->{perfdata}}, @{$child->{nagios}->{perfdata}}); +} + + +sub calculate_result { + my $self = shift; + if ($ENV{NRPE_MULTILINESUPPORT} && + length join(" ", @{$self->{nagios}->{perfdata}}) > 200) { + foreach my $level ("CRITICAL", "WARNING", "UNKNOWN", "OK") { + # first the bad news + if (scalar(@{$self->{nagios}->{messages}->{$ERRORS{$level}}})) { + $self->{nagios_message} .= + "\n".join("\n", @{$self->{nagios}->{messages}->{$ERRORS{$level}}}); + } + } + $self->{nagios_message} =~ s/^\n//g; + $self->{perfdata} = join("\n", @{$self->{nagios}->{perfdata}}); + } else { + foreach my $level ("CRITICAL", "WARNING", "UNKNOWN", "OK") { + # first the bad news + if (scalar(@{$self->{nagios}->{messages}->{$ERRORS{$level}}})) { + $self->{nagios_message} .= + join(", ", @{$self->{nagios}->{messages}->{$ERRORS{$level}}}).", "; + } + } + $self->{nagios_message} =~ s/, $//g; + $self->{perfdata} = join(" ", @{$self->{nagios}->{perfdata}}); + } + foreach my $level ("OK", "UNKNOWN", "WARNING", "CRITICAL") { + if (scalar(@{$self->{nagios}->{messages}->{$ERRORS{$level}}})) { + $self->{nagios_level} = $ERRORS{$level}; + } + } +} + +sub debug { + my $self = shift; + my $msg = shift; + if ($DBD::MySQL::Cluster::verbose) { + printf "%s %s\n", $msg, ref($self); + } +} + +sub connect { + my $self = shift; + my %params = @_; + my $retval = undef; + $self->{tic} = Time::HiRes::time(); + eval { + use POSIX ':signal_h'; + local $SIG{'ALRM'} = sub { + die "alarm\n"; + }; + my $mask = POSIX::SigSet->new( SIGALRM ); + my $action = POSIX::SigAction->new( + sub { die "connection timeout\n" ; }, $mask); + my $oldaction = POSIX::SigAction->new(); + sigaction(SIGALRM ,$action ,$oldaction ); + alarm($self->{timeout} - 1); # 1 second before the global unknown timeout + my $ndb_mgm = "ndb_mgm"; + $params{hostname} = "127.0.0.1" if ! $params{hostname}; + $ndb_mgm .= sprintf " --ndb-connectstring=%s", $params{hostname} + if $params{hostname}; + $ndb_mgm .= sprintf ":%d", $params{port} + if $params{port}; + $self->{show} = `$ndb_mgm -e show 2>&1`; + if ($? == -1) { + $self->add_nagios_critical("ndb_mgm failed to execute $!"); + } elsif ($? & 127) { + $self->add_nagios_critical("ndb_mgm failed to execute $!"); + } elsif ($? >> 8 != 0) { + $self->add_nagios_critical("ndb_mgm unable to connect"); + } else { + if ($self->{show} !~ /Cluster Configuration/) { + $self->add_nagios_critical("got no cluster configuration"); + } else { + $retval = 1; + } + } + }; + if ($@) { + $self->{errstr} = $@; + $self->{errstr} =~ s/at $0 .*//g; + chomp $self->{errstr}; + $self->add_nagios_critical($self->{errstr}); + $retval = undef; + } + $self->{tac} = Time::HiRes::time(); + return $retval; +} + +sub trace { + my $self = shift; + my $format = shift; + $self->{trace} = -f "/tmp/check_mysql_health.trace" ? 1 : 0; + if ($self->{verbose}) { + printf("%s: ", scalar localtime); + printf($format, @_); + } + if ($self->{trace}) { + my $logfh = new IO::File; + $logfh->autoflush(1); + if ($logfh->open("/tmp/check_mysql_health.trace", "a")) { + $logfh->printf("%s: ", scalar localtime); + $logfh->printf($format, @_); + $logfh->printf("\n"); + $logfh->close(); + } + } +} + +sub DESTROY { + my $self = shift; + my $handle1 = "null"; + my $handle2 = "null"; + if (defined $self->{handle}) { + $handle1 = ref($self->{handle}); + if (defined $self->{handle}->{handle}) { + $handle2 = ref($self->{handle}->{handle}); + } + } + $self->trace(sprintf "DESTROY %s with handle %s %s", ref($self), $handle1, $handle2); + if (ref($self) eq "DBD::MySQL::Cluster") { + } + $self->trace(sprintf "DESTROY %s exit with handle %s %s", ref($self), $handle1, $handle2); + if (ref($self) eq "DBD::MySQL::Cluster") { + #printf "humpftata\n"; + } +} + +sub save_state { + my $self = shift; + my %params = @_; + my $extension = ""; + mkdir $params{statefilesdir} unless -d $params{statefilesdir}; + my $statefile = sprintf "%s/%s_%s", + $params{statefilesdir}, $params{hostname}, $params{mode}; + $extension .= $params{differenciator} ? "_".$params{differenciator} : ""; + $extension .= $params{socket} ? "_".$params{socket} : ""; + $extension .= $params{port} ? "_".$params{port} : ""; + $extension .= $params{database} ? "_".$params{database} : ""; + $extension .= $params{tablespace} ? "_".$params{tablespace} : ""; + $extension .= $params{datafile} ? "_".$params{datafile} : ""; + $extension .= $params{name} ? "_".$params{name} : ""; + $extension =~ s/\//_/g; + $extension =~ s/\(/_/g; + $extension =~ s/\)/_/g; + $extension =~ s/\*/_/g; + $extension =~ s/\s/_/g; + $statefile .= $extension; + $statefile = lc $statefile; + open(STATE, ">$statefile"); + if ((ref($params{save}) eq "HASH") && exists $params{save}->{timestamp}) { + $params{save}->{localtime} = scalar localtime $params{save}->{timestamp}; + } + printf STATE Data::Dumper::Dumper($params{save}); + close STATE; + $self->debug(sprintf "saved %s to %s", + Data::Dumper::Dumper($params{save}), $statefile); +} + +sub load_state { + my $self = shift; + my %params = @_; + my $extension = ""; + my $statefile = sprintf "%s/%s_%s", + $params{statefilesdir}, $params{hostname}, $params{mode}; + $extension .= $params{differenciator} ? "_".$params{differenciator} : ""; + $extension .= $params{socket} ? "_".$params{socket} : ""; + $extension .= $params{port} ? "_".$params{port} : ""; + $extension .= $params{database} ? "_".$params{database} : ""; + $extension .= $params{tablespace} ? "_".$params{tablespace} : ""; + $extension .= $params{datafile} ? "_".$params{datafile} : ""; + $extension .= $params{name} ? "_".$params{name} : ""; + $extension =~ s/\//_/g; + $extension =~ s/\(/_/g; + $extension =~ s/\)/_/g; + $extension =~ s/\*/_/g; + $extension =~ s/\s/_/g; + $statefile .= $extension; + $statefile = lc $statefile; + if ( -f $statefile) { + our $VAR1; + eval { + require $statefile; + }; + if($@) { +printf "rumms\n"; + } + $self->debug(sprintf "load %s", Data::Dumper::Dumper($VAR1)); + return $VAR1; + } else { + return undef; + } +} + +sub valdiff { + my $self = shift; + my $pparams = shift; + my %params = %{$pparams}; + my @keys = @_; + my $last_values = $self->load_state(%params) || eval { + my $empty_events = {}; + foreach (@keys) { + $empty_events->{$_} = 0; + } + $empty_events->{timestamp} = 0; + $empty_events; + }; + foreach (@keys) { + $self->{'delta_'.$_} = $self->{$_} - $last_values->{$_}; + $self->debug(sprintf "delta_%s %f", $_, $self->{'delta_'.$_}); + } + $self->{'delta_timestamp'} = time - $last_values->{timestamp}; + $params{save} = eval { + my $empty_events = {}; + foreach (@keys) { + $empty_events->{$_} = $self->{$_}; + } + $empty_events->{timestamp} = time; + $empty_events; + }; + $self->save_state(%params); +} + +sub requires_version { + my $self = shift; + my $version = shift; + my @instances = DBD::MySQL::Cluster::return_clusters(); + my $instversion = $instances[0]->{version}; + if (! $self->version_is_minimum($version)) { + $self->add_nagios($ERRORS{UNKNOWN}, + sprintf "not implemented/possible for MySQL release %s", $instversion); + } +} + +sub version_is_minimum { + # the current version is newer or equal + my $self = shift; + my $version = shift; + my $newer = 1; + my @instances = DBD::MySQL::Cluster::return_clusters(); + my @v1 = map { $_ eq "x" ? 0 : $_ } split(/\./, $version); + my @v2 = split(/\./, $instances[0]->{version}); + if (scalar(@v1) > scalar(@v2)) { + push(@v2, (0) x (scalar(@v1) - scalar(@v2))); + } elsif (scalar(@v2) > scalar(@v1)) { + push(@v1, (0) x (scalar(@v2) - scalar(@v1))); + } + foreach my $pos (0..$#v1) { + if ($v2[$pos] > $v1[$pos]) { + $newer = 1; + last; + } elsif ($v2[$pos] < $v1[$pos]) { + $newer = 0; + last; + } + } + #printf STDERR "check if %s os minimum %s\n", join(".", @v2), join(".", @v1); + return $newer; +} + +sub instance_rac { + my $self = shift; + my @instances = DBD::MySQL::Cluster::return_clusters(); + return (lc $instances[0]->{parallel} eq "yes") ? 1 : 0; +} + +sub instance_thread { + my $self = shift; + my @instances = DBD::MySQL::Cluster::return_clusters(); + return $instances[0]->{thread}; +} + +sub windows_cluster { + my $self = shift; + my @instances = DBD::MySQL::Cluster::return_clusters(); + if ($instances[0]->{os} =~ /Win/i) { + return 1; + } else { + return 0; + } +} + +sub system_vartmpdir { + my $self = shift; + if ($^O =~ /MSWin/) { + return $self->system_tmpdir(); + } else { + return "/var/tmp/check_mysql_health"; + } +} + +sub system_oldvartmpdir { + my $self = shift; + return "/tmp"; +} + +sub system_tmpdir { + my $self = shift; + if ($^O =~ /MSWin/) { + return $ENV{TEMP} if defined $ENV{TEMP}; + return $ENV{TMP} if defined $ENV{TMP}; + return File::Spec->catfile($ENV{windir}, 'Temp') + if defined $ENV{windir}; + return 'C:\Temp'; + } else { + return "/tmp"; + } +} + + +package DBD::MySQL::Cluster::Node; + +use strict; + +our @ISA = qw(DBD::MySQL::Cluster); + + +sub new { + my $class = shift; + my %params = @_; + my $self = { + mode => $params{mode}, + timeout => $params{timeout}, + type => $params{type}, + id => $params{id}, + status => $params{status}, + }; + bless $self, $class; + $self->init(%params); + if ($params{type} eq "NDB") { + bless $self, "DBD::MySQL::Cluster::Node::NDB"; + $self->init(%params); + } + return $self; +} + +sub init { + my $self = shift; + my %params = @_; + if ($self->{status} =~ /@(\d+\.\d+\.\d+\.\d+)\s/) { + $self->{addr} = $1; + $self->{connected} = 1; + } elsif ($self->{status} =~ /accepting connect from (\d+\.\d+\.\d+\.\d+)/) { + $self->{addr} = $1; + $self->{connected} = 0; + } + if ($self->{status} =~ /starting,/) { + $self->{status} = "starting"; + } elsif ($self->{status} =~ /shutting,/) { + $self->{status} = "shutting"; + } else { + $self->{status} = $self->{connected} ? "running" : "dead"; + } +} + + +package DBD::MySQL::Cluster::Node::NDB; + +use strict; + +our @ISA = qw(DBD::MySQL::Cluster::Node); + + +sub init { + my $self = shift; + my %params = @_; + if ($self->{status} =~ /Nodegroup:\s*(\d+)/) { + $self->{nodegroup} = $1; + } + $self->{master} = ($self->{status} =~ /Master\)/) ? 1 : 0; +} + + +package Extraopts; + +use strict; +use File::Basename; +use Data::Dumper; + +sub new { + my $class = shift; + my %params = @_; + my $self = { + file => $params{file}, + commandline => $params{commandline}, + config => {}, + section => 'default_no_section', + }; + bless $self, $class; + $self->prepare_file_and_section(); + $self->init(); + return $self; +} + +sub prepare_file_and_section { + my $self = shift; + if (! defined $self->{file}) { + # ./check_stuff --extra-opts + $self->{section} = basename($0); + $self->{file} = $self->get_default_file(); + } elsif ($self->{file} =~ /^[^@]+$/) { + # ./check_stuff --extra-opts=special_opts + $self->{section} = $self->{file}; + $self->{file} = $self->get_default_file(); + } elsif ($self->{file} =~ /^@(.*)/) { + # ./check_stuff --extra-opts=@/etc/myconfig.ini + $self->{section} = basename($0); + $self->{file} = $1; + } elsif ($self->{file} =~ /^(.*?)@(.*)/) { + # ./check_stuff --extra-opts=special_opts@/etc/myconfig.ini + $self->{section} = $1; + $self->{file} = $2; + } +} + +sub get_default_file { + my $self = shift; + foreach my $default (qw(/etc/nagios/plugins.ini + /usr/local/nagios/etc/plugins.ini + /usr/local/etc/nagios/plugins.ini + /etc/opt/nagios/plugins.ini + /etc/nagios-plugins.ini + /usr/local/etc/nagios-plugins.ini + /etc/opt/nagios-plugins.ini)) { + if (-f $default) { + return $default; + } + } + return undef; +} + +sub init { + my $self = shift; + if (! defined $self->{file}) { + $self->{errors} = sprintf 'no extra-opts file specified and no default file found'; + } elsif (! -f $self->{file}) { + $self->{errors} = sprintf 'could not open %s', $self->{file}; + } else { + my $data = do { local (@ARGV, $/) = $self->{file}; <> }; + my $in_section = 'default_no_section'; + foreach my $line (split(/\n/, $data)) { + if ($line =~ /\[(.*)\]/) { + $in_section = $1; + } elsif ($line =~ /(.*?)\s*=\s*(.*)/) { + $self->{config}->{$in_section}->{$1} = $2; + } + } + } +} + +sub is_valid { + my $self = shift; + return ! exists $self->{errors}; +} + +sub overwrite { + my $self = shift; + my %commandline = (); + if (scalar(keys %{$self->{config}->{default_no_section}}) > 0) { + foreach (keys %{$self->{config}->{default_no_section}}) { + $commandline{$_} = $self->{config}->{default_no_section}->{$_}; + } + } + if (exists $self->{config}->{$self->{section}}) { + foreach (keys %{$self->{config}->{$self->{section}}}) { + $commandline{$_} = $self->{config}->{$self->{section}}->{$_}; + } + } + foreach (keys %commandline) { + if (! exists $self->{commandline}->{$_}) { + $self->{commandline}->{$_} = $commandline{$_}; + } + } +} + + + +package main; + +use strict; +use Getopt::Long qw(:config no_ignore_case); +use File::Basename; +use lib dirname($0); + + + +use vars qw ($PROGNAME $REVISION $CONTACT $TIMEOUT $STATEFILESDIR $needs_restart %commandline); + +$PROGNAME = "check_mysql_health"; +$REVISION = '$Revision: 2.1.7 $'; +$CONTACT = 'gerhard.lausser@consol.de'; +$TIMEOUT = 60; +$STATEFILESDIR = '/var/tmp/check_mysql_health'; +$needs_restart = 0; + +my @modes = ( + ['server::connectiontime', + 'connection-time', undef, + 'Time to connect to the server' ], + ['server::uptime', + 'uptime', undef, + 'Time the server is running' ], + ['server::instance::connectedthreads', + 'threads-connected', undef, + 'Number of currently open connections' ], + ['server::instance::threadcachehitrate', + 'threadcache-hitrate', undef, + 'Hit rate of the thread-cache' ], + ['server::instance::createdthreads', + 'threads-created', undef, + 'Number of threads created per sec' ], + ['server::instance::runningthreads', + 'threads-running', undef, + 'Number of currently running threads' ], + ['server::instance::cachedthreads', + 'threads-cached', undef, + 'Number of currently cached threads' ], + ['server::instance::abortedconnects', + 'connects-aborted', undef, + 'Number of aborted connections per sec' ], + ['server::instance::abortedclients', + 'clients-aborted', undef, + 'Number of aborted connections (because the client died) per sec' ], + ['server::instance::replication::slavelag', + 'slave-lag', ['replication-slave-lag'], + 'Seconds behind master' ], + ['server::instance::replication::slaveiorunning', + 'slave-io-running', ['replication-slave-io-running'], + 'Slave io running: Yes' ], + ['server::instance::replication::slavesqlrunning', + 'slave-sql-running', ['replication-slave-sql-running'], + 'Slave sql running: Yes' ], + ['server::instance::querycachehitrate', + 'qcache-hitrate', ['querycache-hitrate'], + 'Query cache hitrate' ], + ['server::instance::querycachelowmemprunes', + 'qcache-lowmem-prunes', ['querycache-lowmem-prunes'], + 'Query cache entries pruned because of low memory' ], + ['server::instance::myisam::keycache::hitrate', + 'keycache-hitrate', ['myisam-keycache-hitrate'], + 'MyISAM key cache hitrate' ], + ['server::instance::innodb::bufferpool::hitrate', + 'bufferpool-hitrate', ['innodb-bufferpool-hitrate'], + 'InnoDB buffer pool hitrate' ], + ['server::instance::innodb::bufferpool::waitfree', + 'bufferpool-wait-free', ['innodb-bufferpool-wait-free'], + 'InnoDB buffer pool waits for clean page available' ], + ['server::instance::innodb::logwaits', + 'log-waits', ['innodb-log-waits'], + 'InnoDB log waits because of a too small log buffer' ], + ['server::instance::tablecachehitrate', + 'tablecache-hitrate', undef, + 'Table cache hitrate' ], + ['server::instance::tablelockcontention', + 'table-lock-contention', undef, + 'Table lock contention' ], + ['server::instance::tableindexusage', + 'index-usage', undef, + 'Usage of indices' ], + ['server::instance::tabletmpondisk', + 'tmp-disk-tables', undef, + 'Percent of temp tables created on disk' ], + ['server::instance::needoptimize', + 'table-fragmentation', undef, + 'Show tables which should be optimized' ], + ['server::instance::openfiles', + 'open-files', undef, + 'Percent of opened files' ], + ['server::instance::slowqueries', + 'slow-queries', undef, + 'Slow queries' ], + ['server::instance::longprocs', + 'long-running-procs', undef, + 'long running processes' ], + ['cluster::ndbdrunning', + 'cluster-ndbd-running', undef, + 'ndnd nodes are up and running' ], + ['server::sql', + 'sql', undef, + 'any sql command returning a single number' ], +); + +# rrd data store names are limited to 19 characters +my %labels = ( + bufferpool_hitrate => { + groundwork => 'bp_hitrate', + }, + bufferpool_hitrate_now => { + groundwork => 'bp_hitrate_now', + }, + bufferpool_free_waits_rate => { + groundwork => 'bp_freewaits', + }, + innodb_log_waits_rate => { + groundwork => 'inno_log_waits', + }, + keycache_hitrate => { + groundwork => 'kc_hitrate', + }, + keycache_hitrate_now => { + groundwork => 'kc_hitrate_now', + }, + threads_created_per_sec => { + groundwork => 'thrds_creat_per_s', + }, + connects_aborted_per_sec => { + groundwork => 'conn_abrt_per_s', + }, + clients_aborted_per_sec => { + groundwork => 'clnt_abrt_per_s', + }, + thread_cache_hitrate => { + groundwork => 'tc_hitrate', + }, + thread_cache_hitrate_now => { + groundwork => 'tc_hitrate_now', + }, + qcache_lowmem_prunes_rate => { + groundwork => 'qc_lowm_prnsrate', + }, + slow_queries_rate => { + groundwork => 'slow_q_rate', + }, + tablecache_hitrate => { + groundwork => 'tac_hitrate', + }, + tablecache_fillrate => { + groundwork => 'tac_fillrate', + }, + tablelock_contention => { + groundwork => 'tl_contention', + }, + tablelock_contention_now => { + groundwork => 'tl_contention_now', + }, + pct_tmp_table_on_disk => { + groundwork => 'tmptab_on_disk', + }, + pct_tmp_table_on_disk_now => { + groundwork => 'tmptab_on_disk_now', + }, +); + +sub print_usage () { + print <<EOUS; + Usage: + $PROGNAME [-v] [-t <timeout>] [[--hostname <hostname>] + [--port <port> | --socket <socket>] + --username <username> --password <password>] --mode <mode> + [--method mysql] + $PROGNAME [-h | --help] + $PROGNAME [-V | --version] + + Options: + --hostname + the database server's hostname + --port + the database's port. (default: 3306) + --socket + the database's unix socket. + --username + the mysql db user + --password + the mysql db user's password + --database + the database's name. (default: information_schema) + --warning + the warning range + --critical + the critical range + --mode + the mode of the plugin. select one of the following keywords: +EOUS + my $longest = length ((reverse sort {length $a <=> length $b} map { $_->[1] } @modes)[0]); + my $format = " %-". + (length ((reverse sort {length $a <=> length $b} map { $_->[1] } @modes)[0])). + "s\t(%s)\n"; + foreach (@modes) { + printf $format, $_->[1], $_->[3]; + } + printf "\n"; + print <<EOUS; + --name + the name of something that needs to be further specified, + currently only used for sql statements + --name2 + if name is a sql statement, this statement would appear in + the output and the performance data. This can be ugly, so + name2 can be used to appear instead. + --regexp + if this parameter is used, name will be interpreted as a + regular expression. + --units + one of %, KB, MB, GB. This is used for a better output of mode=sql + and for specifying thresholds for mode=tablespace-free + --labelformat + one of pnp4nagios (which is the default) or groundwork. + It is used to shorten performance data labels to 19 characters. + + In mode sql you can url-encode the statement so you will not have to mess + around with special characters in your Nagios service definitions. + Instead of + --name="select count(*) from v\$session where status = 'ACTIVE'" + you can say + --name=select%20count%28%2A%29%20from%20v%24session%20where%20status%20%3D%20%27ACTIVE%27 + For your convenience you can call check_mysql_health with the --mode encode + option and it will encode the standard input. + + You can find the full documentation at + http://www.consol.de/opensource/nagios/check-mysql-health + +EOUS + +} + +sub print_help () { + print "Copyright (c) 2009 Gerhard Lausser\n\n"; + print "\n"; + print " Check various parameters of MySQL databases \n"; + print "\n"; + print_usage(); + support(); +} + + +sub print_revision ($$) { + my $commandName = shift; + my $pluginRevision = shift; + $pluginRevision =~ s/^\$Revision: //; + $pluginRevision =~ s/ \$\s*$//; + print "$commandName ($pluginRevision)\n"; + print "This nagios plugin comes with ABSOLUTELY NO WARRANTY. You may redistribute\ncopies of this plugin under the terms of the GNU General Public License.\n"; +} + +sub support () { + my $support='Send email to gerhard.lausser@consol.de if you have questions\nregarding use of this software. \nPlease include version information with all correspondence (when possible,\nuse output from the --version option of the plugin itself).\n'; + $support =~ s/@/\@/g; + $support =~ s/\\n/\n/g; + print $support; +} + +sub contact_author ($$) { + my $item = shift; + my $strangepattern = shift; + if ($commandline{verbose}) { + printf STDERR + "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n". + "You found a line which is not recognized by %s\n". + "This means, certain components of your system cannot be checked.\n". + "Please contact the author %s and\nsend him the following output:\n\n". + "%s /%s/\n\nThank you!\n". + "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n", + $PROGNAME, $CONTACT, $item, $strangepattern; + } +} + +%commandline = (); +my @params = ( + "timeout|t=i", + "version|V", + "help|h", + "verbose|v", + "debug|d", + "hostname|H=s", + "database=s", + "port|P=s", + "socket|S=s", + "username|u=s", + "password|p=s", + "mode|m=s", + "name=s", + "name2=s", + "regexp", + "perfdata", + "warning=s", + "critical=s", + "dbthresholds:s", + "absolute|a", + "environment|e=s%", + "method=s", + "runas|r=s", + "scream", + "shell", + "eyecandy", + "encode", + "units=s", + "lookback=i", + "3", + "statefilesdir=s", + "with-mymodules-dyn-dir=s", + "report=s", + "labelformat=s", + "extra-opts:s"); + +if (! GetOptions(\%commandline, @params)) { + print_help(); + exit $ERRORS{UNKNOWN}; +} + +if (exists $commandline{'extra-opts'}) { + # read the extra file and overwrite other parameters + my $extras = Extraopts->new(file => $commandline{'extra-opts'}, commandline => + \%commandline); + if (! $extras->is_valid()) { + printf "extra-opts are not valid: %s\n", $extras->{errors}; + exit $ERRORS{UNKNOWN}; + } else { + $extras->overwrite(); + } +} + +if (exists $commandline{version}) { + print_revision($PROGNAME, $REVISION); + exit $ERRORS{OK}; +} + +if (exists $commandline{help}) { + print_help(); + exit $ERRORS{OK}; +} elsif (! exists $commandline{mode}) { + printf "Please select a mode\n"; + print_help(); + exit $ERRORS{OK}; +} + +if ($commandline{mode} eq "encode") { + my $input = <>; + chomp $input; + $input =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg; + printf "%s\n", $input; + exit $ERRORS{OK}; +} + +if (exists $commandline{3}) { + $ENV{NRPE_MULTILINESUPPORT} = 1; +} + +if (exists $commandline{timeout}) { + $TIMEOUT = $commandline{timeout}; +} + +if (exists $commandline{verbose}) { + $DBD::MySQL::Server::verbose = exists $commandline{verbose}; +} + +if (exists $commandline{scream}) { +# $DBD::MySQL::Server::hysterical = exists $commandline{scream}; +} + +if (exists $commandline{method}) { + # snmp or mysql cmdline +} else { + $commandline{method} = "dbi"; +} + +if (exists $commandline{report}) { + # short, long, html +} else { + $commandline{report} = "long"; +} + +if (exists $commandline{labelformat}) { + # groundwork +} else { + $commandline{labelformat} = "pnp4nagios"; +} + +if (exists $commandline{'with-mymodules-dyn-dir'}) { + $DBD::MySQL::Server::my_modules_dyn_dir = $commandline{'with-mymodules-dyn-dir'}; +} else { + $DBD::MySQL::Server::my_modules_dyn_dir = '/usr/local/nagios/libexec'; +} + +if (exists $commandline{environment}) { + # if the desired environment variable values are different from + # the environment of this running script, then a restart is necessary. + # because setting $ENV does _not_ change the environment of the running script. + foreach (keys %{$commandline{environment}}) { + if ((! $ENV{$_}) || ($ENV{$_} ne $commandline{environment}->{$_})) { + $needs_restart = 1; + $ENV{$_} = $commandline{environment}->{$_}; + printf STDERR "new %s=%s forces restart\n", $_, $ENV{$_} + if $DBD::MySQL::Server::verbose; + } + } + # e.g. called with --runas dbnagio. shlib_path environment variable is stripped + # during the sudo. + # so the perl interpreter starts without a shlib_path. but --runas cares for + # a --environment shlib_path=... + # so setting the environment variable in the code above and restarting the + # perl interpreter will help it find shared libs +} + +if (exists $commandline{runas}) { + # remove the runas parameter + # exec sudo $0 ... the remaining parameters + $needs_restart = 1; + # if the calling script has a path for shared libs and there is no --environment + # parameter then the called script surely needs the variable too. + foreach my $important_env qw(LD_LIBRARY_PATH SHLIB_PATH + ORACLE_HOME TNS_ADMIN ORA_NLS ORA_NLS33 ORA_NLS10) { + if ($ENV{$important_env} && ! scalar(grep { /^$important_env=/ } + keys %{$commandline{environment}})) { + $commandline{environment}->{$important_env} = $ENV{$important_env}; + printf STDERR "add important --environment %s=%s\n", + $important_env, $ENV{$important_env} if $DBD::MySQL::Server::verbose; + } + } +} + +if ($needs_restart) { + my @newargv = (); + my $runas = undef; + if (exists $commandline{runas}) { + $runas = $commandline{runas}; + delete $commandline{runas}; + } + foreach my $option (keys %commandline) { + if (grep { /^$option/ && /=/ } @params) { + if (ref ($commandline{$option}) eq "HASH") { + foreach (keys %{$commandline{$option}}) { + push(@newargv, sprintf "--%s", $option); + push(@newargv, sprintf "%s=%s", $_, $commandline{$option}->{$_}); + } + } else { + push(@newargv, sprintf "--%s", $option); + push(@newargv, sprintf "%s", $commandline{$option}); + } + } else { + push(@newargv, sprintf "--%s", $option); + } + } + if ($runas) { + exec "sudo", "-S", "-u", $runas, $0, @newargv; + } else { + exec $0, @newargv; + # this makes sure that even a SHLIB or LD_LIBRARY_PATH are set correctly + # when the perl interpreter starts. Setting them during runtime does not + # help loading e.g. libclntsh.so + } + exit; +} + +if (exists $commandline{shell}) { + # forget what you see here. + system("/bin/sh"); +} + +if (! exists $commandline{statefilesdir}) { + if (exists $ENV{OMD_ROOT}) { + $commandline{statefilesdir} = $ENV{OMD_ROOT}."/var/tmp/check_mysql_health"; + } else { + $commandline{statefilesdir} = $STATEFILESDIR; + } +} + +if (exists $commandline{name}) { + # objects can be encoded like an url + # with s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg; + if (($commandline{mode} ne "sql") || + (($commandline{mode} eq "sql") && + ($commandline{name} =~ /select%20/i))) { # protect ... like '%cac%' ... from decoding + $commandline{name} =~ s/\%([A-Fa-f0-9]{2})/pack('C', hex($1))/seg; + } + if ($commandline{name} =~ /^0$/) { + # without this, $params{selectname} would be treated like undef + $commandline{name} = "00"; + } +} + +$SIG{'ALRM'} = sub { + printf "UNKNOWN - %s timed out after %d seconds\n", $PROGNAME, $TIMEOUT; + exit $ERRORS{UNKNOWN}; +}; +alarm($TIMEOUT); + +my $nagios_level = $ERRORS{UNKNOWN}; +my $nagios_message = ""; +my $perfdata = ""; +if ($commandline{mode} =~ /^my-([^\-.]+)/) { + my $param = $commandline{mode}; + $param =~ s/\-/::/g; + push(@modes, [$param, $commandline{mode}, undef, 'my extension']); +} elsif ((! grep { $commandline{mode} eq $_ } map { $_->[1] } @modes) && + (! grep { $commandline{mode} eq $_ } map { defined $_->[2] ? @{$_->[2]} : () } @modes)) { + printf "UNKNOWN - mode %s\n", $commandline{mode}; + print_usage(); + exit 3; +} + +my %params = ( + timeout => $TIMEOUT, + mode => ( + map { $_->[0] } + grep { + ($commandline{mode} eq $_->[1]) || + ( defined $_->[2] && grep { $commandline{mode} eq $_ } @{$_->[2]}) + } @modes + )[0], + cmdlinemode => $commandline{mode}, + method => $commandline{method} || + $ENV{NAGIOS__SERVICEMYSQL_METH} || + $ENV{NAGIOS__HOSTMYSQL_METH} || 'dbi', + hostname => $commandline{hostname} || + $ENV{NAGIOS__SERVICEMYSQL_HOST} || + $ENV{NAGIOS__HOSTMYSQL_HOST} || 'localhost', + database => $commandline{database} || + $ENV{NAGIOS__SERVICEMYSQL_DATABASE} || + $ENV{NAGIOS__HOSTMYSQL_DATABASE} || 'information_schema', + port => $commandline{port} || (($commandline{mode} =~ /^cluster/) ? + ($ENV{NAGIOS__SERVICENDBMGM_PORT} || $ENV{NAGIOS__HOSTNDBMGM_PORT} || 1186) : + ($ENV{NAGIOS__SERVICEMYSQL_PORT} || $ENV{NAGIOS__HOSTMYSQL_PORT} || 3306)), + socket => $commandline{socket} || + $ENV{NAGIOS__SERVICEMYSQL_SOCKET} || + $ENV{NAGIOS__HOSTMYSQL_SOCKET}, + username => $commandline{username} || + $ENV{NAGIOS__SERVICEMYSQL_USER} || + $ENV{NAGIOS__HOSTMYSQL_USER}, + password => $commandline{password} || + $ENV{NAGIOS__SERVICEMYSQL_PASS} || + $ENV{NAGIOS__HOSTMYSQL_PASS}, + warningrange => $commandline{warning}, + criticalrange => $commandline{critical}, + dbthresholds => $commandline{dbthresholds}, + absolute => $commandline{absolute}, + lookback => $commandline{lookback}, + selectname => $commandline{name} || $commandline{tablespace} || $commandline{datafile}, + regexp => $commandline{regexp}, + name => $commandline{name}, + name2 => $commandline{name2} || $commandline{name}, + units => $commandline{units}, + lookback => $commandline{lookback} || 0, + eyecandy => $commandline{eyecandy}, + statefilesdir => $commandline{statefilesdir}, + verbose => $commandline{verbose}, + report => $commandline{report}, + labelformat => $commandline{labelformat}, +); + +my $server = undef; +my $cluster = undef; + +if ($params{mode} =~ /^(server|my)/) { + $server = DBD::MySQL::Server->new(%params); + $server->nagios(%params); + $server->calculate_result(\%labels); + $nagios_message = $server->{nagios_message}; + $nagios_level = $server->{nagios_level}; + $perfdata = $server->{perfdata}; +} elsif ($params{mode} =~ /^cluster/) { + $cluster = DBD::MySQL::Cluster->new(%params); + $cluster->nagios(%params); + $cluster->calculate_result(\%labels); + $nagios_message = $cluster->{nagios_message}; + $nagios_level = $cluster->{nagios_level}; + $perfdata = $cluster->{perfdata}; +} + +printf "%s - %s", $ERRORCODES{$nagios_level}, $nagios_message; +printf " | %s", $perfdata if $perfdata; +printf "\n"; +exit $nagios_level; + + +__END__ + + diff --git a/puppet/modules/nagios/files/plugins/check_openvpn_server.pl b/puppet/modules/nagios/files/plugins/check_openvpn_server.pl new file mode 100755 index 00000000..b74ace89 --- /dev/null +++ b/puppet/modules/nagios/files/plugins/check_openvpn_server.pl @@ -0,0 +1,109 @@ +#!/usr/bin/perl +# +# Filaname: check_openvpn +# Created: 2012-06-15 +# Website: http://blog.kernelpicnic.net +# +# Description: +# This script is for verifying the status of an OpenVPN daemon. It has been +# written to integrate directly with Nagios / Opsview. +# +# Usage: +# check_openvpn [OPTIONS]... +# +# -H, --hostname Host to check +# -p, --port Port number to check +# -h, --help Display help. +# +############################################################################# + +# Custom library path for Nagis modules. +use lib qw ( /usr/local/nagios/perl/lib ); + +# Enforce sanity. +use strict; +use warnings; + +# Required modules. +use Getopt::Long qw(:config no_ignore_case); +use Nagios::Plugin; +use IO::Socket; + +# Define defaults. +my $help = 0; +my $timeout = 5; + +# Ensure required variables are set. +my($hostname, $port); + +my $options = GetOptions( + "hostname|H=s" => \$hostname, + "timeout|t=s" => \$timeout, + "port|p=s" => \$port, + "help|h" => \$help, +); + +# Check if help has been requested. +if($help || !$hostname || !$port) { + + printf("\n"); + printf("Usage: check_openvpn [OPTIONS]...\n\n"); + printf(" -H, --hostname Host to check\n"); + printf(" -p, --port Port number to check\n"); + printf(" -h, --help This help page\n"); + printf(" -t, --timeout Socket timeout\n"); + printf("\n"); + + exit(-1); + +} + +# Setup a new Nagios::Plugin object. +my $nagios = Nagios::Plugin->new(); + +# Define the check string to send to the OpenVPN server - as binary due +# to non-printable characters. +my $check_string = "001110000011001010010010011011101000000100010001110" + ."100110110101010110011000000000000000000000000000000" + ."0000000000"; + +# Attempt to setup a socket to the specified host. +my $host_sock = IO::Socket::INET->new( + Proto => 'udp', + PeerAddr => $hostname, + PeerPort => $port, +); + +# Ensure we have a socket. +if(!$host_sock) { + $nagios->nagios_exit(UNKNOWN, "Unable to bind socket"); +} + +# Fire off the check request. +$host_sock->send(pack("B*", $check_string)); + +# Wait for $timeout for response for a response, otherwise, fail. +my $response; + +eval { + + # Define how to handle ALARM. + local $SIG{ALRM} = sub { + $nagios->nagios_exit(CRITICAL, "No response received"); + }; + + # Set the alarm for the given timeout value. + alarm($timeout); + + # Check for response. + $host_sock->recv($response, 1) + or $nagios->nagios_exit(CRITICAL, "No response received"); + + # Alright, response received, cancel alarm. + alarm(0); + 1; + +}; + +# Reply received, return okay. +$nagios->nagios_exit(OK, "Response received from host"); diff --git a/puppet/modules/nagios/files/plugins/check_pop3_login b/puppet/modules/nagios/files/plugins/check_pop3_login new file mode 100644 index 00000000..4eb29b88 --- /dev/null +++ b/puppet/modules/nagios/files/plugins/check_pop3_login @@ -0,0 +1,83 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +# -*- Mode: Python -*- +# +# Copyright (C) 2006 Bertera Pietro <pietro@bertera.it> +# Copyright (C) 2015 mh <mh@immerda.ch> +# Response time monitoring with perfdata modification by Ivan Savcic <isavcic@gmail.com> and Milos Buncic, 2012. +# Derived from: https://github.com/isavcic/check_imap_login + +# This file may be distributed and/or modified under the terms of +# the GNU General Public License version 2 as published by +# the Free Software Foundation. +# This file is distributed without any warranty; without even the implied +# warranty of merchantability or fitness for a particular purpose. + +import sys, os, poplib, getopt +from time import time + +def usage(): + print sys.argv[0] + " -u <user> -p <password> -H <host> [-s] -w <warning threshold (sec)> -c <critical threshold (sec)>\n -s is for using POP3s" + +def main(): + try: + opts, args = getopt.getopt(sys.argv[1:], "u:p:sH:w:c:") + except getopt.GetoptError: + usage() + return 3 + + user = host = password = use_ssl = warning = critical = None + + for o, a in opts: + if o == "-u": + user = a + elif o == "-p": + password = a + elif o == "-s": + use_ssl = True + elif o == "-H": + host = a + elif o == "-w": + warning = float(a) + elif o == "-c": + critical = float(a) + + if user == None or password == None or host == None or warning == None or critical == None: + usage() + return 1 + + if use_ssl: + M = poplib.POP3_SSL(host=host) + else: + M = poplib.POP3(host) + + timestamp = time() + + try: + M.getwelcome() + M.user(user) + M.pass_(password) + except Exception, e: + print "CRITICAL POP3 Login Failed: %s" % e + return 2 + + M.quit() + + timestamp = time() - timestamp + + if timestamp < warning: + status = "OK" + exitcode = 0 + if timestamp >= warning: + status = "WARNING" + exitcode = 1 + if timestamp >= critical: + status = "CRITICAL" + exitcode = 2 + + print '%s POP3 Login | response_time=%.3fs;%.3f;%.3f' % (status, timestamp, warning, critical) + + return exitcode + +if __name__ == "__main__": + sys.exit(main()) diff --git a/puppet/modules/nagios/files/pnp4nagios/action.gif b/puppet/modules/nagios/files/pnp4nagios/action.gif Binary files differnew file mode 100644 index 00000000..96571a40 --- /dev/null +++ b/puppet/modules/nagios/files/pnp4nagios/action.gif diff --git a/puppet/modules/nagios/files/pnp4nagios/apache.conf b/puppet/modules/nagios/files/pnp4nagios/apache.conf new file mode 100644 index 00000000..816bf05c --- /dev/null +++ b/puppet/modules/nagios/files/pnp4nagios/apache.conf @@ -0,0 +1,31 @@ +# SAMPLE CONFIG SNIPPETS FOR APACHE WEB SERVER + +Alias /pnp4nagios "/usr/share/pnp4nagios/html" + +<Directory "/usr/share/pnp4nagios/html"> + AllowOverride None + Order allow,deny + Allow from all + # + # Use the same value as defined in nagios.conf + # + AuthName "Nagios Access" + AuthType Basic + AuthUserFile /etc/nagios3/htpasswd.users + Require valid-user + <IfModule mod_rewrite.c> + # Turn on URL rewriting + RewriteEngine On + Options FollowSymLinks + # Installation directory + RewriteBase /pnp4nagios/ + # Protect application and system files from being viewed + RewriteRule ^(application|modules|system) - [F,L] + # Allow any files or directories that exist to be displayed directly + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + # Rewrite all other URLs to index.php/URL + RewriteRule .* index.php/$0 [PT,L] + </IfModule> + DirectoryIndex index.php +</Directory> diff --git a/puppet/modules/nagios/files/pnp4nagios/npcd b/puppet/modules/nagios/files/pnp4nagios/npcd new file mode 100644 index 00000000..64b3d4d9 --- /dev/null +++ b/puppet/modules/nagios/files/pnp4nagios/npcd @@ -0,0 +1,8 @@ +# Default settings for the NPCD init script. + +# Should NPCD be started? ("yes" to enable) +RUN="yes" + +# Additional options that are passed to the daemon. +DAEMON_OPTS="-d -f /etc/pnp4nagios/npcd.cfg" + diff --git a/puppet/modules/nagios/files/pnp4nagios/pnp4nagios-popup-templates.cfg b/puppet/modules/nagios/files/pnp4nagios/pnp4nagios-popup-templates.cfg new file mode 100644 index 00000000..de17d841 --- /dev/null +++ b/puppet/modules/nagios/files/pnp4nagios/pnp4nagios-popup-templates.cfg @@ -0,0 +1,31 @@ +# http://docs.pnp4nagios.org/de/pnp-0.6/webfe + +define host { + name host-pnp + action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_' class='tips' rel='/pnp4nagios/index.php/popup?host=$HOSTNAME$&srv=_HOST_ + register 0 +} + +define service { + name srv-pnp + action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=$SERVICEDESC$' class='tips' rel='/pnp4nagios/index.php/popup?host=$HOSTNAME$&srv=$SERVICEDESC$ + register 0 +} + +# templates for explicit use, i.e. +# use => 'generic-host-pnp' + +define host { + name generic-host-pnp + use generic-host,host-pnp +# action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_ + register 0 +} + +define service { + name generic-service-pnp + use generic-service,srv-pnp +# action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_ + register 0 +} + diff --git a/puppet/modules/nagios/files/pnp4nagios/pnp4nagios-templates.cfg b/puppet/modules/nagios/files/pnp4nagios/pnp4nagios-templates.cfg new file mode 100644 index 00000000..64c51865 --- /dev/null +++ b/puppet/modules/nagios/files/pnp4nagios/pnp4nagios-templates.cfg @@ -0,0 +1,33 @@ +# http://docs.pnp4nagios.org/de/pnp-0.6/webfe + +# templates for additional use, i.e. +# use => 'generic-host,host-pnp' +define host { + name host-pnp + action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_ + register 0 +} + +define service { + name srv-pnp + action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=$SERVICEDESC$ + register 0 +} + +# templates for explicit use, i.e. +# use => 'generic-host-pnp' + +define host { + name generic-host-pnp + use generic-host,host-pnp +# action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_ + register 0 +} + +define service { + name generic-service-pnp + use generic-service,srv-pnp +# action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_ + register 0 +} + diff --git a/puppet/modules/nagios/files/pnp4nagios/status-header.ssi b/puppet/modules/nagios/files/pnp4nagios/status-header.ssi new file mode 100644 index 00000000..472be3a2 --- /dev/null +++ b/puppet/modules/nagios/files/pnp4nagios/status-header.ssi @@ -0,0 +1,8 @@ +<script src="/pnp4nagios/media/js/jquery-min.js" type="text/javascript"></script> +<script src="/pnp4nagios/media/js/jquery.cluetip.js" type="text/javascript"></script> +<script type="text/javascript"> +$(document).ready(function() { + $('a.tips').cluetip({ajaxCache: false, dropShadow: false,showTitle: false }); +}); +</script> + diff --git a/puppet/modules/nagios/images/nagiosgraph.gif b/puppet/modules/nagios/images/nagiosgraph.gif Binary files differnew file mode 100644 index 00000000..068082af --- /dev/null +++ b/puppet/modules/nagios/images/nagiosgraph.gif diff --git a/puppet/modules/nagios/manifests/apache.pp b/puppet/modules/nagios/manifests/apache.pp new file mode 100644 index 00000000..87fe3d2f --- /dev/null +++ b/puppet/modules/nagios/manifests/apache.pp @@ -0,0 +1,15 @@ +# setup naguis together with apache +class nagios::apache( + $allow_external_cmd = false, + $manage_shorewall = false, + $manage_munin = false, + $storeconfigs = true +) { + class{'::nagios': + httpd => 'apache', + allow_external_cmd => $allow_external_cmd, + manage_munin => $manage_munin, + manage_shorewall => $manage_shorewall, + storeconfigs => $storeconfigs + } +} diff --git a/puppet/modules/nagios/manifests/base.pp b/puppet/modules/nagios/manifests/base.pp new file mode 100644 index 00000000..18d5c12f --- /dev/null +++ b/puppet/modules/nagios/manifests/base.pp @@ -0,0 +1,144 @@ +# basic stuff for nagios +class nagios::base { + # include the variables + include ::nagios::defaults::vars + + package { 'nagios': + ensure => present, + } + + service { 'nagios': + ensure => running, + enable => $nagios::service_at_boot, + require => Package['nagios'], + } + + $cfg_dir = $nagios::defaults::vars::int_cfgdir + # this file should contain all the nagios_puppet-paths: + file{ + 'nagios_cfgdir': + ensure => directory, + path => $cfg_dir, + alias => nagios_confd, + recurse => true, + purge => true, + force => true, + require => Package['nagios'], + notify => Service['nagios'], + owner => root, + group => root, + mode => '0755'; + 'nagios_main_cfg': + path => "${cfg_dir}/nagios.cfg", + source => [ "puppet:///modules/site_nagios/configs/${::fqdn}/nagios.cfg", + "puppet:///modules/site_nagios/configs/${::operatingsystem}/nagios.cfg", + 'puppet:///modules/site_nagios/configs/nagios.cfg', + "puppet:///modules/nagios/configs/${::operatingsystem}/nagios.cfg", + 'puppet:///modules/nagios/configs/nagios.cfg' ], + notify => Service['nagios'], + owner => root, + group => root, + mode => '0644'; + 'nagios_cgi_cfg': + path => "${cfg_dir}/cgi.cfg", + source => [ "puppet:///modules/site_nagios/configs/${::fqdn}/cgi.cfg", + "puppet:///modules/site_nagios/configs/${::operatingsystem}/cgi.cfg", + 'puppet:///modules/site_nagios/configs/cgi.cfg', + "puppet:///modules/nagios/configs/${::operatingsystem}/cgi.cfg", + 'puppet:///modules/nagios/configs/cgi.cfg' ], + notify => Service['apache'], + owner => 'root', + group => 0, + mode => '0644'; + 'nagios_htpasswd': + path => "${cfg_dir}/htpasswd.users", + source => [ 'puppet:///modules/site_nagios/htpasswd.users', + 'puppet:///modules/nagios/htpasswd.users' ], + owner => root, + group => apache, + mode => '0640'; + 'nagios_resource_cfg': + path => "${cfg_dir}/resource.cfg", + source => [ "puppet:///modules/site_nagios/configs/${::operatingsystem}/private/resource.cfg.${::architecture}", + "puppet:///modules/nagios/configs/${::operatingsystem}/private/resource.cfg.${::architecture}" ], + notify => Service['nagios'], + owner => root, + group => nagios, + mode => '0640'; + } + + if $cfg_dir == '/etc/nagios3' { + file{'/etc/nagios': + ensure => link, + target => $cfg_dir, + before => File['nagios_cfgdir'], + } + } + + file{ + [ "${cfg_dir}/nagios_command.cfg", + "${cfg_dir}/nagios_contact.cfg", + "${cfg_dir}/nagios_contactgroup.cfg", + "${cfg_dir}/nagios_host.cfg", + "${cfg_dir}/nagios_hostdependency.cfg", + "${cfg_dir}/nagios_hostescalation.cfg", + "${cfg_dir}/nagios_hostextinfo.cfg", + "${cfg_dir}/nagios_hostgroup.cfg", + "${cfg_dir}/nagios_hostgroupescalation.cfg", + "${cfg_dir}/nagios_service.cfg", + "${cfg_dir}/nagios_servicedependency.cfg", + "${cfg_dir}/nagios_serviceescalation.cfg", + "${cfg_dir}/nagios_serviceextinfo.cfg", + "${cfg_dir}/nagios_servicegroup.cfg", + "${cfg_dir}/nagios_timeperiod.cfg" ]: + ensure => file, + replace => false, + notify => Service['nagios'], + require => File['nagios_cfgdir'], + owner => root, + group => 0, + mode => '0644'; + } + + resources { + [ + 'nagios_command', + 'nagios_contactgroup', + 'nagios_contact', + 'nagios_hostdependency', + 'nagios_hostescalation', + 'nagios_hostextinfo', + 'nagios_hostgroup', + 'nagios_host', + 'nagios_servicedependency', + 'nagios_serviceescalation', + 'nagios_servicegroup', + 'nagios_serviceextinfo', + 'nagios_service', + 'nagios_timeperiod', + ]: + notify => Service['nagios'], + purge => $::nagios::purge_resources + } + + # make sure nagios resources are defined after nagios is + # installed and the nagios_cfgdir resource is present + File['nagios_cfgdir'] -> Nagios_command <||> + File['nagios_cfgdir'] -> Nagios_contactgroup <||> + File['nagios_cfgdir'] -> Nagios_contact <||> + File['nagios_cfgdir'] -> Nagios_hostdependency <||> + File['nagios_cfgdir'] -> Nagios_hostescalation <||> + File['nagios_cfgdir'] -> Nagios_hostextinfo <||> + File['nagios_cfgdir'] -> Nagios_hostgroup <||> + File['nagios_cfgdir'] -> Nagios_host <||> + File['nagios_cfgdir'] -> Nagios_servicedependency <||> + File['nagios_cfgdir'] -> Nagios_serviceescalation <||> + File['nagios_cfgdir'] -> Nagios_servicegroup <||> + File['nagios_cfgdir'] -> Nagios_serviceextinfo <||> + File['nagios_cfgdir'] -> Nagios_service <||> + File['nagios_cfgdir'] -> Nagios_timeperiod <||> + + if ( $nagios::storeconfigs == true ) { + include ::nagios::storeconfigs + } +} diff --git a/puppet/modules/nagios/manifests/centos.pp b/puppet/modules/nagios/manifests/centos.pp new file mode 100644 index 00000000..f41d46dc --- /dev/null +++ b/puppet/modules/nagios/manifests/centos.pp @@ -0,0 +1,42 @@ +# centos specific changes +class nagios::centos inherits nagios::base { + + package { [ 'nagios-plugins', 'nagios-plugins-smtp','nagios-plugins-http', + 'nagios-plugins-ssh', 'nagios-plugins-tcp', 'nagios-plugins-dig', + 'nagios-plugins-nrpe', 'nagios-plugins-load', 'nagios-plugins-dns', + 'nagios-plugins-ping', 'nagios-plugins-procs', 'nagios-plugins-users', + 'nagios-plugins-ldap', 'nagios-plugins-disk', 'nagios-plugins-swap', + 'nagios-plugins-nagios', 'nagios-plugins-perl', 'nagios-plugins-ntp', + 'nagios-plugins-snmp' ]: + ensure => 'present', + notify => Service['nagios'], + } + + Service['nagios']{ + hasstatus => true, + } + + file{ + 'nagios_private': + ensure => directory, + path => "${nagios::base::cfg_dir}/private", + purge => true, + recurse => true, + notify => Service['nagios'], + owner => root, + group => nagios, + mode => '0750'; + } + File['nagios_resource_cfg']{ + path => "${nagios::base::cfg_dir}/private/resource.cfg", + } + if $nagios::allow_external_cmd { + file{'/var/spool/nagios/cmd': + ensure => 'directory', + require => Package['nagios'], + owner => apache, + group => nagios, + mode => '2660', + } + } +} diff --git a/puppet/modules/nagios/manifests/command/imap_pop3.pp b/puppet/modules/nagios/manifests/command/imap_pop3.pp new file mode 100644 index 00000000..42e4092b --- /dev/null +++ b/puppet/modules/nagios/manifests/command/imap_pop3.pp @@ -0,0 +1,30 @@ +# manage mail checks +class nagios::command::imap_pop3 { + require ::nagios::plugins::mail_login + case $::operatingsystem { + 'Debian','Ubuntu': { } # Debian/Ubuntu already define those checks + default: { + nagios_command { + 'check_imap': + command_line => '$USER1$/check_imap -H $ARG1$ -p $ARG2$'; + } + } + } + + nagios_command { + 'check_imap_ssl': + command_line => '$USER1$/check_imap -H $ARG1$ -p $ARG2$ -S'; + 'check_pop3': + command_line => '$USER1$/check_pop -H $ARG1$ -p $ARG2$'; + 'check_pop3_ssl': + command_line => '$USER1$/check_pop -H $ARG1$ -p $ARG2$ -S'; + 'check_managesieve': + command_line => '$USER1$/check_tcp -H $ARG1$ -p 4190'; + 'check_managesieve_legacy': + command_line => '$USER1$/check_tcp -H $ARG1$ -p 2000'; + 'check_imap_login': + command_line => '$USER1$/check_imap_login -s -H $ARG1$ -u $ARG2$ -p $ARG3$ -w $ARG4$ -c $ARG5$'; + 'check_pop3_login': + command_line => '$USER1$/check_pop3_login -s -H $ARG1$ -u $ARG2$ -p $ARG3$ -w $ARG4$ -c $ARG5$'; + } +} diff --git a/puppet/modules/nagios/manifests/command/nrpe.pp b/puppet/modules/nagios/manifests/command/nrpe.pp new file mode 100644 index 00000000..7539a266 --- /dev/null +++ b/puppet/modules/nagios/manifests/command/nrpe.pp @@ -0,0 +1,14 @@ +class nagios::command::nrpe { + + # this command runs a program $ARG1$ with arguments $ARG2$ + nagios_command { + 'check_nrpe': + command_line => '/usr/lib/nagios/plugins/check_nrpe -H $HOSTADDRESS$ -c $ARG1$ -a $ARG2$' + } + + # this command runs a program $ARG1$ with no arguments + nagios_command { + 'check_nrpe_1arg': + command_line => '/usr/lib/nagios/plugins/check_nrpe -H $HOSTADDRESS$ -c $ARG1$' + } +} diff --git a/puppet/modules/nagios/manifests/command/nrpe_timeout.pp b/puppet/modules/nagios/manifests/command/nrpe_timeout.pp new file mode 100644 index 00000000..799f2fc3 --- /dev/null +++ b/puppet/modules/nagios/manifests/command/nrpe_timeout.pp @@ -0,0 +1,11 @@ +class nagios::command::nrpe_timeout { + nagios_command { + 'check_nrpe_timeout': + command_line => '/usr/lib/nagios/plugins/check_nrpe -t $ARG1$ -H $HOSTADDRESS$ -c $ARG2$ -a $ARG3$', + require => Package['nagios-nrpe-server']; + + 'check_nrpe_1arg_timeout': + command_line => '/usr/lib/nagios/plugins/check_nrpe -t $ARG1$ -H $HOSTADDRESS$ -c $ARG2$', + require => Package['nagios-nrpe-server'] + } +} diff --git a/puppet/modules/nagios/manifests/command/smtp.pp b/puppet/modules/nagios/manifests/command/smtp.pp new file mode 100644 index 00000000..29d97f8b --- /dev/null +++ b/puppet/modules/nagios/manifests/command/smtp.pp @@ -0,0 +1,22 @@ +class nagios::command::smtp { + case $operatingsystem { + debian,ubuntu: { } # Debian/Ubuntu already define those checks + default: { + nagios_command { + 'check_smtp': + command_line => '$USER1$/check_smtp -H $ARG1$ -p $ARG2$'; + 'check_ssmtp': + command_line => '$USER1$/check_ssmtp -H $ARG1$ -p $ARG2$ -S'; + } + } + } + + nagios_command { + 'check_smtp_tls': + command_line => '$USER1$/check_smtp -H $ARG1$ -p $ARG2$ -S'; + 'check_smtp_cert': + command_line => '$USER1$/check_smtp -H $ARG1$ -p $ARG2$ -S -D $ARG3$'; + 'check_ssmtp_cert': + command_line => '$USER1$/check_ssmtp -H $ARG1$ -p $ARG2$ -S -D $ARG3$'; + } +} diff --git a/puppet/modules/nagios/manifests/debian.pp b/puppet/modules/nagios/manifests/debian.pp new file mode 100644 index 00000000..39af973e --- /dev/null +++ b/puppet/modules/nagios/manifests/debian.pp @@ -0,0 +1,54 @@ +# debian specific things +class nagios::debian inherits nagios::base { + + Package['nagios'] { name => 'nagios3' } + + package { [ 'nagios-plugins', 'nagios-snmp-plugins','nagios-nrpe-plugin' ]: + ensure => 'present', + notify => Service['nagios'], + } + + Service['nagios'] { + name => 'nagios3', + hasstatus => true, + } + + File['nagios_htpasswd', 'nagios_cgi_cfg'] { group => 'www-data' } + + file{ + 'nagios_commands_cfg': + path => "${nagios::defaults::vars::int_cfgdir}/commands.cfg", + notify => Service['nagios'], + owner => root, + group => root, + mode => '0644', + require => Package['nagios']; + "${nagios::defaults::vars::int_cfgdir}/stylesheets": + ensure => directory, + purge => false, + recurse => true, + require => Package['nagios']; + } + + if $nagios::allow_external_cmd { + exec { 'nagios_external_cmd_perms_overrides': + command => 'dpkg-statoverride --update --add nagios www-data 2710 /var/lib/nagios3/rw && dpkg-statoverride --update --add nagios nagios 751 /var/lib/nagios3', + unless => 'dpkg-statoverride --list nagios www-data 2710 /var/lib/nagios3/rw && dpkg-statoverride --list nagios nagios 751 /var/lib/nagios3', + logoutput => false, + notify => Service['nagios'], + require => Package['nagios'], + } + exec { 'nagios_external_cmd_perms_1': + command => 'chmod 0751 /var/lib/nagios3 && chown nagios:nagios /var/lib/nagios3', + unless => 'test "`stat -c "%a %U %G" /var/lib/nagios3`" = "751 nagios nagios"', + notify => Service['nagios'], + require => Package['nagios'], + } + exec { 'nagios_external_cmd_perms_2': + command => 'chmod 2751 /var/lib/nagios3/rw && chown nagios:www-data /var/lib/nagios3/rw', + unless => 'test "`stat -c "%a %U %G" /var/lib/nagios3/rw`" = "2751 nagios www-data"', + notify => Service['nagios'], + require => Package['nagios'], + } + } +} diff --git a/puppet/modules/nagios/manifests/debian/apache.pp b/puppet/modules/nagios/manifests/debian/apache.pp new file mode 100644 index 00000000..17b60c60 --- /dev/null +++ b/puppet/modules/nagios/manifests/debian/apache.pp @@ -0,0 +1,22 @@ +# Handle files that are specifically needed for nagios with apache on debian +# +# Do not include this class directly. It is included by the nagios class and +# needs variables from it. +# +class nagios::debian::apache { + + include ::nagios::defaults::vars + + file { "${nagios::defaults::vars::int_cfgdir}/apache2.conf": + source => [ "puppet:///modules/site_nagios/configs/${::fqdn}/apache2.conf", + 'puppet:///modules/site_nagios/configs/apache2.conf', + 'puppet:///modules/nagios/configs/apache2.conf'], + } + + apache::config::global { 'nagios3.conf': + ensure => link, + target => "${nagios::defaults::vars::int_cfgdir}/apache2.conf", + require => File["${nagios::defaults::vars::int_cfgdir}/apache2.conf"], + } + +} diff --git a/puppet/modules/nagios/manifests/defaults.pp b/puppet/modules/nagios/manifests/defaults.pp new file mode 100644 index 00000000..7c25ac94 --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults.pp @@ -0,0 +1,12 @@ +class nagios::defaults { + + # include some default nagios objects + + include nagios::defaults::commands + include nagios::defaults::contactgroups + include nagios::defaults::contacts + include nagios::defaults::hostgroups + include nagios::defaults::templates + include nagios::defaults::timeperiods + include nagios::defaults::plugins +} diff --git a/puppet/modules/nagios/manifests/defaults/commands.pp b/puppet/modules/nagios/manifests/defaults/commands.pp new file mode 100644 index 00000000..0f24411f --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/commands.pp @@ -0,0 +1,145 @@ +# defaults commands we wanna have available +class nagios::defaults::commands { + + include ::nagios::command::smtp + include ::nagios::command::imap_pop3 + include ::nagios::plugins::horde_login + + # common service commands + case $::operatingsystem { + 'Debian','Ubuntu': { + nagios_command { + 'check_dummy': + command_line => '$USER1$/check_dummy $ARG1$'; + 'check_https_cert': + command_line => '$USER1$/check_http --ssl -C 20 -H $HOSTADDRESS$ -I $HOSTADDRESS$'; + 'check_http_url': + command_line => '$USER1$/check_http -H $ARG1$ -u $ARG2$'; + 'check_http_url_regex': + command_line => '$USER1$/check_http -H $ARG1$ -p $ARG2$ -u $ARG3$ -e $ARG4$'; + 'check_https_url': + command_line => '$USER1$/check_http --ssl -H $ARG1$ -u $ARG2$'; + 'check_https_url_regex': + command_line => '$USER1$/check_http --ssl -H $ARG1$ -u $ARG2$ -e $ARG3$'; + 'check_mysql_db': + command_line => '$USER1$/check_mysql -H $ARG1$ -P $ARG2$ -u $ARG3$ -p $ARG4$ -d $ARG5$'; + 'check_ntp_time': + command_line => '$USER1$/check_ntp_time -H $HOSTADDRESS$ -w 0.5 -c 1'; + 'check_silc': + command_line => '$USER1$/check_tcp -p 706 -H $ARG1$'; + 'check_sobby': + command_line => '$USER1$/check_tcp -H $ARG1$ -p $ARG2$'; + 'check_jabber': + command_line => '$USER1$/check_jabber -H $ARG1$'; + 'check_git': + command_line => '$USER1$/check_tcp -H $ARG1$ -p 9418'; + } + } + default: { + nagios_command { + 'check_dummy': + command_line => '$USER1$/check_dummy $ARG1$'; + 'check_ping': + command_line => '$USER1$/check_ping -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$'; + 'check-host-alive': + command_line => '$USER1$/check_ping -H $HOSTADDRESS$ -w 5000,100% -c 5000,100% -p 1'; + 'check_tcp': + command_line => '$USER1$/check_tcp -H $HOSTADDRESS$ -p $ARG1$'; + 'check_udp': + command_line => '$USER1$/check_udp -H $HOSTADDRESS$ -p $ARG1$'; + 'check_load': + command_line => '$USER1$/check_load --warning=$ARG1$,$ARG2$,$ARG3$ --critical=$ARG4$,$ARG5$,$ARG6$'; + 'check_disk': + command_line => '$USER1$/check_disk -w $ARG1$ -c $ARG2$ -e -p $ARG3$'; + 'check_all_disks': + command_line => '$USER1$/check_disk -w $ARG1$ -c $ARG2$ -e'; + 'check_ssh': + command_line => '$USER1$/check_ssh $HOSTADDRESS$'; + 'check_ssh_port': + command_line => '$USER1$/check_ssh -p $ARG1$ $HOSTADDRESS$'; + 'check_ssh_port_host': + command_line => '$USER1$/check_ssh -p $ARG1$ $ARG2$'; + 'check_http': + command_line => '$USER1$/check_http -H $HOSTADDRESS$ -I $HOSTADDRESS$'; + 'check_https': + command_line => '$USER1$/check_http --ssl -H $HOSTADDRESS$ -I $HOSTADDRESS$'; + 'check_https_cert': + command_line => '$USER1$/check_http --ssl -C 20 -H $HOSTADDRESS$ -I $HOSTADDRESS$'; + 'check_http_url': + command_line => '$USER1$/check_http -H $ARG1$ -u $ARG2$'; + 'check_http_url_regex': + command_line => '$USER1$/check_http -H $ARG1$ -p $ARG2$ -u $ARG3$ -e $ARG4$'; + 'check_https_url': + command_line => '$USER1$/check_http --ssl -H $ARG1$ -u $ARG2$'; + 'check_https_url_regex': + command_line => '$USER1$/check_http --ssl -H $ARG1$ -u $ARG2$ -e $ARG3$'; + 'check_mysql': + command_line => '$USER1$/check_mysql -H $ARG1$ -P $ARG2$ -u $ARG3$ -p $ARG4$'; + 'check_mysql_db': + command_line => '$USER1$/check_mysql -H $ARG1$ -P $ARG2$ -u $ARG3$ -p $ARG4$ -d $ARG5$'; + 'check_ntp_time': + command_line => '$USER1$/check_ntp_time -H $HOSTADDRESS$ -w 0.5 -c 1'; + 'check_silc': + command_line => '$USER1$/check_tcp -p 706 -H $ARG1$'; + 'check_sobby': + command_line => '$USER1$/check_tcp -H $ARG1$ -p $ARG2$'; + 'check_jabber': + command_line => '$USER1$/check_jabber -H $ARG1$'; + 'check_git': + command_line => '$USER1$/check_tcp -H $ARG1$ -p 9418'; + } + } + } + + # commands for services defined by other modules + + nagios_command { + # from apache module + 'http_port': + command_line => '$USER1$/check_http -p $ARG1$ -H $HOSTADDRESS$ -I $HOSTADDRESS$'; + + 'check_http_port_url_content': + command_line => '$USER1$/check_http -H $ARG1$ -p $ARG2$ -u $ARG3$ -s $ARG4$'; + 'check_https_port_url_content': + command_line => '$USER1$/check_http --ssl -H $ARG1$ -p $ARG2$ -u $ARG3$ -s $ARG4$'; + 'check_http_url_content': + command_line => '$USER1$/check_http -H $ARG1$ -u $ARG2$ -s $ARG3$'; + 'check_https_url_content': + command_line => '$USER1$/check_http --ssl -H $ARG1$ -u $ARG2$ -s $ARG3$'; + + # from bind module + 'check_dig2': + command_line => '$USER1$/check_dig -H $HOSTADDRESS$ -l $ARG1$ --record_type=$ARG2$'; + + # from mysql module + 'check_mysql_health': + command_line => '$USER1$/check_mysql_health --hostname $ARG1$ --port $ARG2$ --username $ARG3$ --password $ARG4$ --mode $ARG5$ --database $ARG6$ $ARG7$ $ARG8$'; + + # better check_dns + 'check_dns2': + command_line => '$USER1$/check_dns2 -c $ARG1$ A $ARG2$'; + + # dnsbl checking + 'check_dnsbl': + command_line => '$USER1$/check_dnsbl -H $ARG1$'; + } + + # notification commands + + $mail_cmd_location = $::operatingsystem ? { + 'CentOS' => '/bin/mail', + default => '/usr/bin/mail' + } + + case $::lsbdistcodename { + 'wheezy': { } + default: { + nagios_command { + 'notify-host-by-email': + command_line => "/usr/bin/printf \"%b\" \"***** Nagios *****\\n\\nNotification Type: \$NOTIFICATIONTYPE\$\\n\\nHost: \$HOSTNAME\$ (\$HOSTALIAS\$)\\nAddress: \$HOSTADDRESS\$\\nState: \$HOSTSTATE\$\\nDuration: \$HOSTDURATION\$\\n\\nDate/Time: \$LONGDATETIME\$\\n\\nOutput: \$HOSTOUTPUT\$\" | ${mail_cmd_location} -s \"\$NOTIFICATIONTYPE\$: \$HOSTSTATE\$ - \$HOSTNAME\$\" \$CONTACTEMAIL\$"; + 'notify-service-by-email': + command_line => "/usr/bin/printf \"%b\" \"***** Nagios *****\\n\\nNotification Type: \$NOTIFICATIONTYPE\$\\n\\nHost: \$HOSTNAME\$ (\$HOSTALIAS\$)\\nAddress: \$HOSTADDRESS\$\\n\\nService: \$SERVICEDESC\$\\nState: \$SERVICESTATE\$\\nDuration: \$SERVICEDURATION\$\\n\\nDate/Time: \$LONGDATETIME\$\\n\\nOutput: \$SERVICEOUTPUT\$\" | ${mail_cmd_location} -s \"\$NOTIFICATIONTYPE\$: \$SERVICESTATE\$ - \$HOSTALIAS\$/\$SERVICEDESC\$\" \$CONTACTEMAIL\$"; + } + } + } +} diff --git a/puppet/modules/nagios/manifests/defaults/contactgroups.pp b/puppet/modules/nagios/manifests/defaults/contactgroups.pp new file mode 100644 index 00000000..f5affc60 --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/contactgroups.pp @@ -0,0 +1,9 @@ +class nagios::defaults::contactgroups { + + nagios_contactgroup { + 'admins': + alias => 'Nagios Administrators', + members => 'root', + } + +} diff --git a/puppet/modules/nagios/manifests/defaults/contacts.pp b/puppet/modules/nagios/manifests/defaults/contacts.pp new file mode 100644 index 00000000..0252b5a8 --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/contacts.pp @@ -0,0 +1,15 @@ +class nagios::defaults::contacts { + + nagios_contact { + 'root': + alias => 'Root', + service_notification_period => '24x7', + host_notification_period => '24x7', + service_notification_options => 'w,u,c,r', + host_notification_options => 'd,r', + service_notification_commands => 'notify-service-by-email', + host_notification_commands => 'notify-host-by-email', + email => 'root@localhost', + } + +} diff --git a/puppet/modules/nagios/manifests/defaults/host_templates.pp b/puppet/modules/nagios/manifests/defaults/host_templates.pp new file mode 100644 index 00000000..0f47324a --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/host_templates.pp @@ -0,0 +1,24 @@ +class nagios::defaults::host_templates { + + # this inoperative for the moment, see : + # http://projects.reductivelabs.com/issues/1180 + + nagios_host { + 'generic-host': + notifications_enabled => '1', + event_handler_enabled => '1', + flap_detection_enabled => '1', + failure_prediction_enabled => '1', + process_perf_data => '1', + retain_status_information => '1', + retain_nonstatus_information => '1', + check_command => 'check-host-alive', + max_check_attempts => '10', + notification_interval => '0', + notification_period => '24x7', + notification_options => 'd,u,r', + contact_groups => 'admins', + register => '0', + } + +} diff --git a/puppet/modules/nagios/manifests/defaults/hostgroups.pp b/puppet/modules/nagios/manifests/defaults/hostgroups.pp new file mode 100644 index 00000000..8715adee --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/hostgroups.pp @@ -0,0 +1,11 @@ +class nagios::defaults::hostgroups { + nagios_hostgroup { + 'all': + alias => 'All Servers', + members => '*'; + 'debian-servers': + alias => 'Debian GNU/Linux Servers'; + 'centos-servers': + alias => 'CentOS GNU/Linux Servers'; + } +} diff --git a/puppet/modules/nagios/manifests/defaults/plugins.pp b/puppet/modules/nagios/manifests/defaults/plugins.pp new file mode 100644 index 00000000..abd8b528 --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/plugins.pp @@ -0,0 +1,10 @@ +class nagios::defaults::plugins { + nagios::plugin { + 'check_mysql_health': + source => 'nagios/plugins/check_mysql_health'; + 'check_dns2': + source => 'nagios/plugins/check_dns2'; + 'check_dnsbl': + source => 'nagios/plugins/check_dnsbl'; + } +} diff --git a/puppet/modules/nagios/manifests/defaults/pnp4nagios.pp b/puppet/modules/nagios/manifests/defaults/pnp4nagios.pp new file mode 100644 index 00000000..58676c5a --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/pnp4nagios.pp @@ -0,0 +1,14 @@ +# configure default cmds for pnp4nagios +class nagios::defaults::pnp4nagios { + + # performance data cmds + # http://docs.pnp4nagios.org/de/pnp-0.6/config#bulk_mode_mit_npcd + nagios_command { + 'process-service-perfdata-file-pnp4nagios-bulk-npcd': + command_line => '/bin/mv /var/lib/nagios3/service-perfdata /var/spool/pnp4nagios/npcd/service-perfdata.$TIMET$', + require => Package['nagios']; + 'process-host-perfdata-file-pnp4nagios-bulk-npcd': + command_line => '/bin/mv /var/lib/nagios3/host-perfdata /var/spool/pnp4nagios/npcd/host-perfdata.$TIMET$', + require => Package['nagios']; + } +} diff --git a/puppet/modules/nagios/manifests/defaults/service_templates.pp b/puppet/modules/nagios/manifests/defaults/service_templates.pp new file mode 100644 index 00000000..e39441a1 --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/service_templates.pp @@ -0,0 +1,32 @@ +# define the generic service template +class nagios::defaults::service_templates { + + # this inoperative for the moment, see : + # http://projects.reductivelabs.com/issues/1180 + + nagios_service { + 'generic-service': + active_checks_enabled => '1', + passive_checks_enabled => '1', + parallelize_check => '1', + obsess_over_service => '1', + check_freshness => '0', + notifications_enabled => '1', + event_handler_enabled => '1', + flap_detection_enabled => '1', + failure_prediction_enabled => '1', + process_perf_data => '1', + retain_status_information => '1', + retain_nonstatus_information => '1', + notification_interval => '0', + is_volatile => '0', + check_period => '24x7', + check_interval => '5', + retry_check_interval => '1', + max_check_attempts => '4', + notification_period => '24x7', + notification_options => 'w,u,c,r', + contact_groups => 'admins', + register => '0', + } +} diff --git a/puppet/modules/nagios/manifests/defaults/templates.pp b/puppet/modules/nagios/manifests/defaults/templates.pp new file mode 100644 index 00000000..5158189c --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/templates.pp @@ -0,0 +1,17 @@ +# manage nagios_templates +class nagios::defaults::templates { + include nagios::defaults::vars + + file { 'nagios_templates': + path => "${nagios::defaults::vars::int_cfgdir}/nagios_templates.cfg", + source => [ "puppet:///modules/site_nagios/configs/${::fqdn}/nagios_templates.cfg", + "puppet:///modules/site_nagios/configs/${::operatingsystem}/nagios_templates.cfg", + 'puppet:///modules/site_nagios/configs/nagios_templates.cfg', + "puppet:///modules/nagios/configs/${::operatingsystem}/nagios_templates.cfg", + 'puppet:///modules/nagios/configs/nagios_templates.cfg' ], + notify => Service['nagios'], + owner => root, + group => root, + mode => '0644'; + } +} diff --git a/puppet/modules/nagios/manifests/defaults/timeperiods.pp b/puppet/modules/nagios/manifests/defaults/timeperiods.pp new file mode 100644 index 00000000..0d05118a --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/timeperiods.pp @@ -0,0 +1,33 @@ +class nagios::defaults::timeperiods { + + nagios_timeperiod { + '24x7': + alias => '24 Hours A Day, 7 Days A Week', + sunday => '00:00-24:00', + monday => '00:00-24:00', + tuesday => '00:00-24:00', + wednesday => '00:00-24:00', + thursday => '00:00-24:00', + friday => '00:00-24:00', + saturday => '00:00-24:00'; + 'workhours': + alias => 'Standard Work Hours', + monday => '09:00-17:00', + tuesday => '09:00-17:00', + wednesday => '09:00-17:00', + thursday => '09:00-17:00', + friday => '09:00-17:00'; + 'nonworkhours': + alias => 'Non-Work Hours', + sunday => '00:00-24:00', + monday => '00:00-09:00,17:00-24:00', + tuesday => '00:00-09:00,17:00-24:00', + wednesday => '00:00-09:00,17:00-24:00', + thursday => '00:00-09:00,17:00-24:00', + friday => '00:00-09:00,17:00-24:00', + saturday => '00:00-24:00'; + 'never': + alias => 'Never'; + } + +} diff --git a/puppet/modules/nagios/manifests/defaults/vars.pp b/puppet/modules/nagios/manifests/defaults/vars.pp new file mode 100644 index 00000000..e1a62245 --- /dev/null +++ b/puppet/modules/nagios/manifests/defaults/vars.pp @@ -0,0 +1,11 @@ +# some default vars +class nagios::defaults::vars { + case $nagios::cfgdir { + '': { $int_cfgdir = $::operatingsystem ? { + centos => '/etc/nagios', + default => '/etc/nagios3' + } + } + default: { $int_cfgdir = $nagios::cfgdir } + } +} diff --git a/puppet/modules/nagios/manifests/headless.pp b/puppet/modules/nagios/manifests/headless.pp new file mode 100644 index 00000000..ba8af8f4 --- /dev/null +++ b/puppet/modules/nagios/manifests/headless.pp @@ -0,0 +1,5 @@ +class nagios::headless { + class { 'nagios': + httpd => 'absent', + } +} diff --git a/puppet/modules/nagios/manifests/init.pp b/puppet/modules/nagios/manifests/init.pp new file mode 100644 index 00000000..e3421a0a --- /dev/null +++ b/puppet/modules/nagios/manifests/init.pp @@ -0,0 +1,56 @@ +# +# nagios module +# nagios.pp - everything nagios related +# +# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at> +# Copyright 2008, admin(at)immerda.ch +# Copyright 2008, Puzzle ITC GmbH +# Marcel Haerry haerry+puppet(at)puzzle.ch +# Simon Josi josi+puppet(at)puzzle.ch +# +# This program is free software; you can redistribute +# it and/or modify it under the terms of the GNU +# General Public License version 3 as published by +# the Free Software Foundation. +# + +# manage nagios +class nagios( + $httpd = 'apache', + $allow_external_cmd = false, + $manage_shorewall = false, + $manage_munin = false, + $service_atboot = true, + $purge_resources = true, + $gpgkey_checks = {}, + $storeconfigs = true +) { + case $nagios::httpd { + 'absent': { } + 'lighttpd': { include ::lighttpd } + 'apache': { + include ::apache + if $::operatingsystem == 'Debian' { + include ::nagios::debian::apache + } + } + default: { include ::apache } + } + case $::operatingsystem { + 'centos': { + $cfgdir = '/etc/nagios' + include ::nagios::centos + } + 'debian': { + $cfgdir = '/etc/nagios3' + include ::nagios::debian + } + default: { + fail("No such operatingsystem: ${::operatingsystem} yet defined") + } + } + if $manage_munin { + include ::nagios::munin + } + create_resources('nagios::service::gpgkey',$gpgkey_checks) +} diff --git a/puppet/modules/nagios/manifests/irc_bot.pp b/puppet/modules/nagios/manifests/irc_bot.pp new file mode 100644 index 00000000..7e934ef1 --- /dev/null +++ b/puppet/modules/nagios/manifests/irc_bot.pp @@ -0,0 +1,50 @@ +class nagios::irc_bot( + $nsa_socket = 'absent', + $nsa_server, + $nsa_port = 6667, + $nsa_nickname, + $nsa_password = '', + $nsa_channel, + $nsa_pidfile = 'absent', + $nsa_realname = 'Nagios', + $nsa_usenotices = false, + $nsa_commandfile = 'absent' +) { + $real_nsa_socket = $nsa_socket ? { + 'absent' => $::operatingsystem ? { + centos => '/var/run/nagios-nsa/nsa.socket', + default => '/var/run/nagios3/nsa.socket' + }, + default => $nsa_socket, + } + $real_nsa_pidfile = $nsa_pidfile ? { + 'absent' => $::operatingsystem ? { + centos => '/var/run/nagios-nsa/nsa.pid', + default => '/var/run/nagios3/nsa.pid' + }, + default => $nsa_pidfile, + } + $real_nsa_commandfile = $nsa_commandfile ? { + 'absent' => $::operatingsystem ? { + centos => '/var/spool/nagios/cmd/nagios.cmd', + default => '/var/lib/nagios3/rw/nagios.cmd' + }, + default => $nsa_commandfile, + } + + case $::operatingsystem { + centos: { + include nagios::irc_bot::centos + } + debian,ubuntu: { + include nagios::irc_bot::debian + } + default: { + include nagios::irc_bot::base + } + } + + if $nagios::manage_shorewall { + include shorewall::rules::out::irc + } +} diff --git a/puppet/modules/nagios/manifests/irc_bot/base.pp b/puppet/modules/nagios/manifests/irc_bot/base.pp new file mode 100644 index 00000000..fff9da4f --- /dev/null +++ b/puppet/modules/nagios/manifests/irc_bot/base.pp @@ -0,0 +1,41 @@ +class nagios::irc_bot::base { + file { + '/usr/local/bin/riseup-nagios-client.pl': + source => 'puppet:///modules/nagios/irc_bot/riseup-nagios-client.pl', + owner => root, group => 0, mode => '0755'; + + '/usr/local/bin/riseup-nagios-server.pl': + source => 'puppet:///modules/nagios/irc_bot/riseup-nagios-server.pl', + owner => root, group => 0, mode => '0755'; + + '/etc/init.d/nagios-nsa': + content => template("nagios/irc_bot/${::operatingsystem}/nagios-nsa.sh.erb"), + require => File['/usr/local/bin/riseup-nagios-server.pl'], + owner => root, group => 0, mode => '0755'; + + '/etc/nagios_nsa.cfg': + ensure => present, + content => template('nagios/irc_bot/nsa.cfg.erb'), + owner => nagios, group => 0, mode => '0400', + notify => Service['nagios-nsa']; + } + + package { 'libnet-irc-perl': + ensure => present, + } + + service { 'nagios-nsa': + ensure => 'running', + hasstatus => true, + require => [ File['/etc/nagios_nsa.cfg'], + Package['libnet-irc-perl'], + Service['nagios'] ], + } + + nagios_command { + 'notify-by-irc': + command_line => '/usr/local/bin/riseup-nagios-client.pl "$HOSTNAME$ ($SERVICEDESC$) $NOTIFICATIONTYPE$ n.$SERVICEATTEMPT$ $SERVICESTATETYPE$ $SERVICEEXECUTIONTIME$s $SERVICELATENCY$s $SERVICEOUTPUT$ $SERVICEPERFDATA$"'; + 'host-notify-by-irc': + command_line => '/usr/local/bin/riseup-nagios-client.pl "$HOSTNAME$ ($HOSTALIAS$) $NOTIFICATIONTYPE$ n.$HOSTATTEMPT$ $HOSTSTATETYPE$ took $HOSTEXECUTIONTIME$s $HOSTOUTPUT$ $HOSTPERFDATA$ $HOSTLATENCY$s"'; + } +} diff --git a/puppet/modules/nagios/manifests/irc_bot/centos.pp b/puppet/modules/nagios/manifests/irc_bot/centos.pp new file mode 100644 index 00000000..d7b19063 --- /dev/null +++ b/puppet/modules/nagios/manifests/irc_bot/centos.pp @@ -0,0 +1,9 @@ +class nagios::irc_bot::centos inherits nagios::irc_bot::base { + Package['libnet-irc-perl']{ + name => 'perl-Net-IRC', + } + + Service['nagios-nsa']{ + enable => true, + } +} diff --git a/puppet/modules/nagios/manifests/irc_bot/debian.pp b/puppet/modules/nagios/manifests/irc_bot/debian.pp new file mode 100644 index 00000000..93ea64b8 --- /dev/null +++ b/puppet/modules/nagios/manifests/irc_bot/debian.pp @@ -0,0 +1,8 @@ +class nagios::irc_bot::debian inherits nagios::irc_bot::base { + exec { "nagios_nsa_init_script": + command => "/usr/sbin/update-rc.d nagios-nsa defaults", + unless => "/bin/ls /etc/rc3.d/ | /bin/grep nagios-nsa", + require => File["/etc/init.d/nagios-nsa"], + before => Service['nagios-nsa'], + } +} diff --git a/puppet/modules/nagios/manifests/irc_bot/disable.pp b/puppet/modules/nagios/manifests/irc_bot/disable.pp new file mode 100644 index 00000000..d6b7c551 --- /dev/null +++ b/puppet/modules/nagios/manifests/irc_bot/disable.pp @@ -0,0 +1,8 @@ +class nagios::irc_bot::disable inherits nagios::irc_bot::base { + + Service['nagios-nsa'] { + ensure => stopped, + enable => false, + } + +} diff --git a/puppet/modules/nagios/manifests/lighttpd.pp b/puppet/modules/nagios/manifests/lighttpd.pp new file mode 100644 index 00000000..0f298964 --- /dev/null +++ b/puppet/modules/nagios/manifests/lighttpd.pp @@ -0,0 +1,12 @@ +class nagios::lighttpd( + $allow_external_cmd = false, + $manage_shorewall = false, + $manage_munin = false +) { + class{'nagios': + httpd => 'lighttpd', + allow_external_cmd => $allow_external_cmd, + manage_munin => $manage_munin, + manage_shorewall => $manage_shorewall, + } +} diff --git a/puppet/modules/nagios/manifests/munin.pp b/puppet/modules/nagios/manifests/munin.pp new file mode 100644 index 00000000..dc5cc4c3 --- /dev/null +++ b/puppet/modules/nagios/manifests/munin.pp @@ -0,0 +1,19 @@ +class nagios::munin { + include munin::plugins::base + + munin::plugin::deploy { + 'nagios_hosts': + source => 'nagios/munin/nagios_hosts', + config => 'user nagios'; + 'nagios_svc': + source => 'nagios/munin/nagios_svc', + config => 'user nagios'; + 'nagios_perf_hosts': + source => 'nagios/munin/nagios_perf', + config => 'user nagios'; + 'nagios_perf_svc': + source => 'nagios/munin/nagios_perf', + config => 'user nagios'; + } + +} diff --git a/puppet/modules/nagios/manifests/nrpe.pp b/puppet/modules/nagios/manifests/nrpe.pp new file mode 100644 index 00000000..b7984b6e --- /dev/null +++ b/puppet/modules/nagios/manifests/nrpe.pp @@ -0,0 +1,41 @@ +# setup nrpe stuff +class nagios::nrpe ( + $cfg_dir = '', + $pid_file = '', + $plugin_dir = '', + $server_address = '', + $allowed_hosts = '', + $dont_blame = '0', +) { + + if !($dont_blame in ['0', '1']) { + fail('Unrecognized value for $dont_blame, must be one of "0", or "1".') + } + + case $::operatingsystem { + 'FreeBSD': { + if $cfg_dir == '' { $real_cfg_dir = '/usr/local/etc' } + if $pid_file == '' { $real_pid_file = '/var/spool/nagios/nrpe2.pid' } + if $plugin_dir == '' { $real_plugin_dir = '/usr/local/libexec/nagios' } + + include ::nagios::nrpe::freebsd + } + 'Debian': { + if $cfg_dir == '' { $real_cfg_dir = '/etc/nagios' } + if $pid_file == '' { $real_pid_file = '/var/run/nagios/nrpe.pid' } + if $plugin_dir == '' { $real_plugin_dir = '/usr/lib/nagios/plugins' } + include ::nagios::nrpe::linux + } + default: { + if $cfg_dir == '' { $real_cfg_dir = '/etc/nagios' } + if $pid_file == '' { $real_pid_file = '/var/run/nrpe.pid' } + if $plugin_dir == '' { $real_plugin_dir = '/usr/lib/nagios/plugins' } + + case $::kernel { + 'Linux': { include ::nagios::nrpe::linux } + default: { include ::nagios::nrpe::base } + } + } + } + +} diff --git a/puppet/modules/nagios/manifests/nrpe/base.pp b/puppet/modules/nagios/manifests/nrpe/base.pp new file mode 100644 index 00000000..e48e87b4 --- /dev/null +++ b/puppet/modules/nagios/manifests/nrpe/base.pp @@ -0,0 +1,58 @@ +# basic nrpe stuff +class nagios::nrpe::base { + + # Import all variables from entry point + $cfg_dir = $::nagios::nrpe::real_cfg_dir + $pid_file = $::nagios::nrpe::real_pid_file + $plugin_dir = $::nagios::nrpe::real_plugin_dir + $server_address = $::nagios::nrpe::server_address + $allowed_hosts = $::nagios::nrpe::allowed_hosts + $dont_blame = $::nagios::nrpe::dont_blame + + package{['nagios-nrpe-server', 'nagios-plugins-basic', 'libwww-perl']: + ensure => installed; + } + + # Special-case lenny. the package doesn't exist + if $::lsbdistcodename != 'lenny' { + package{'libnagios-plugin-perl': ensure => installed; } + } + + file{ + [ $cfg_dir, "${cfg_dir}/nrpe.d" ]: + ensure => directory; + } + + file { "${cfg_dir}/nrpe.cfg": + content => template('nagios/nrpe/nrpe.cfg'), + owner => root, + group => 0, + mode => '0644'; + } + + # default commands + nagios::nrpe::command{'basic_nrpe': + source => [ "puppet:///modules/site_nagios/configs/nrpe/nrpe_commands.${::fqdn}.cfg", + 'puppet:///modules/site_nagios/configs/nrpe/nrpe_commands.cfg', + 'puppet:///modules/nagios/nrpe/nrpe_commands.cfg' ], + } + # the check for load should be customized for each server based on number + # of CPUs and the type of activity. + $warning_1_threshold = 7 * $::processorcount + $warning_5_threshold = 6 * $::processorcount + $warning_15_threshold = 5 * $::processorcount + $critical_1_threshold = 10 * $::processorcount + $critical_5_threshold = 9 * $::processorcount + $critical_15_threshold = 8 * $::processorcount + nagios::nrpe::command {'check_load': + command_line => "${plugin_dir}/check_load -w ${warning_1_threshold},${warning_5_threshold},${warning_15_threshold} -c ${critical_1_threshold},${critical_5_threshold},${critical_15_threshold}", + } + + service{'nagios-nrpe-server': + ensure => running, + enable => true, + pattern => 'nrpe', + subscribe => File["${cfg_dir}/nrpe.cfg"], + require => Package['nagios-nrpe-server'], + } +} diff --git a/puppet/modules/nagios/manifests/nrpe/command.pp b/puppet/modules/nagios/manifests/nrpe/command.pp new file mode 100644 index 00000000..c66ab986 --- /dev/null +++ b/puppet/modules/nagios/manifests/nrpe/command.pp @@ -0,0 +1,34 @@ +# manage an nrpe command +define nagios::nrpe::command ( + $ensure = present, + $command_line = '', + $source = '', +){ + if ($command_line == '' and $source == '') { + fail('Either one of $command_line or $source must be given to nagios::nrpe::command.' ) + } + + $cfg_dir = $nagios::nrpe::real_cfg_dir + + file{"${cfg_dir}/nrpe.d/${name}_command.cfg": + ensure => $ensure, + notify => Service['nagios-nrpe-server'], + require => File["${cfg_dir}/nrpe.d" ], + owner => 'root', + group => 0, + mode => '0644'; + } + + case $source { + '': { + File["${cfg_dir}/nrpe.d/${name}_command.cfg"] { + content => template('nagios/nrpe/nrpe_command.erb'), + } + } + default: { + File["${cfg_dir}/nrpe.d/${name}_command.cfg"] { + source => $source, + } + } + } +} diff --git a/puppet/modules/nagios/manifests/nrpe/debian.pp b/puppet/modules/nagios/manifests/nrpe/debian.pp new file mode 100644 index 00000000..fcaf8514 --- /dev/null +++ b/puppet/modules/nagios/manifests/nrpe/debian.pp @@ -0,0 +1,6 @@ +class nagios::nrpe::debian inherits nagios::nrpe::base { + include nagios::nrpe::linux + Service['nagios-nrpe-server'] { + hasstatus => false, + } +} diff --git a/puppet/modules/nagios/manifests/nrpe/freebsd.pp b/puppet/modules/nagios/manifests/nrpe/freebsd.pp new file mode 100644 index 00000000..063b79bc --- /dev/null +++ b/puppet/modules/nagios/manifests/nrpe/freebsd.pp @@ -0,0 +1,16 @@ +class nagios::nrpe::freebsd inherits nagios::nrpe::base { + + Package["nagios-nrpe-server"] { name => "nrpe" } + Package["nagios-plugins-basic"] { name => "nagios-plugins" } + Package["libnagios-plugin-perl"] { name => "p5-Nagios-Plugin" } + Package["libwww-perl"] { name => "p5-libwww" } + + # TODO check_cpustats.sh is probably not working as of now. the package 'sysstat' is not available under FreeBSD + + Service["nagios-nrpe-server"] { + pattern => "^/usr/local/sbin/nrpe2", + path => "/usr/local/etc/rc.d", + name => "nrpe2", + hasstatus => "false", + } +} diff --git a/puppet/modules/nagios/manifests/nrpe/linux.pp b/puppet/modules/nagios/manifests/nrpe/linux.pp new file mode 100644 index 00000000..14e007f3 --- /dev/null +++ b/puppet/modules/nagios/manifests/nrpe/linux.pp @@ -0,0 +1,9 @@ +class nagios::nrpe::linux inherits nagios::nrpe::base { + + package { + "nagios-plugins-standard": ensure => present; + "ksh": ensure => present; # for check_cpustats.sh + "sysstat": ensure => present; # for check_cpustats.sh + } + +} diff --git a/puppet/modules/nagios/manifests/nrpe/xinetd.pp b/puppet/modules/nagios/manifests/nrpe/xinetd.pp new file mode 100644 index 00000000..4de0bac6 --- /dev/null +++ b/puppet/modules/nagios/manifests/nrpe/xinetd.pp @@ -0,0 +1,11 @@ +# This is created only to cope with cases where we're not the only ones +# administering a machine and NRPE is running in xinetd. +class nagios::nrpe::xinetd inherits base { + + Service["nagios-nrpe-server"] { + ensure => stopped, + } + + # TODO manage the xinetd config file that glues with NRPE + +} diff --git a/puppet/modules/nagios/manifests/nsca.pp b/puppet/modules/nagios/manifests/nsca.pp new file mode 100644 index 00000000..d5be298c --- /dev/null +++ b/puppet/modules/nagios/manifests/nsca.pp @@ -0,0 +1,3 @@ +class nagios::nsca { + include nagios::nsca::server +} diff --git a/puppet/modules/nagios/manifests/nsca/client.pp b/puppet/modules/nagios/manifests/nsca/client.pp new file mode 100644 index 00000000..6aa8c0b1 --- /dev/null +++ b/puppet/modules/nagios/manifests/nsca/client.pp @@ -0,0 +1,18 @@ +# manage nsca client +class nagios::nsca::client { + + package{'nsca': + ensure => installed + } + + file{'/etc/send_nsca.cfg': + source => [ "puppet:///modules/site_nagios/nsca/${::fqdn}/send_nsca.cfg", + 'puppet:///modules/site_nagios/nsca/send_nsca.cfg', + 'puppet:///modules/nagios/nsca/send_nsca.cfg' ], + owner => 'nagios', + group => 'nogroup', + mode => '0400', + require => Package['nsca']; + } + +} diff --git a/puppet/modules/nagios/manifests/nsca/server.pp b/puppet/modules/nagios/manifests/nsca/server.pp new file mode 100644 index 00000000..8163eec1 --- /dev/null +++ b/puppet/modules/nagios/manifests/nsca/server.pp @@ -0,0 +1,24 @@ +# an nsca server +class nagios::nsca::server { + package{'nsca': + ensure => installed + } + + service { 'nsca': + ensure => running, + hasstatus => false, + hasrestart => true, + require => Package['nsca'], + } + + file { '/etc/nsca.cfg': + source => [ "puppet:///modules/site_nagios/nsca/${::fqdn}/nsca.cfg", + 'puppet:///modules/site_nagios/nsca/nsca.cfg', + 'puppet:///modules/nagios/nsca/nsca.cfg' ], + owner => 'nagios', + group => 'nogroup', + mode => '0400', + notify => Service['nsca'], + } + +} diff --git a/puppet/modules/nagios/manifests/plugin.pp b/puppet/modules/nagios/manifests/plugin.pp new file mode 100644 index 00000000..07938cd2 --- /dev/null +++ b/puppet/modules/nagios/manifests/plugin.pp @@ -0,0 +1,28 @@ +# a wrapper for syncing a plugin +define nagios::plugin( + $source = 'absent', + $ensure = present, +){ + if $::hardwaremodel == 'x86_64' and $::operatingsystem != 'Debian' { + $real_path = "/usr/lib64/nagios/plugins/${name}" + } + else { + $real_path = "/usr/lib/nagios/plugins/${name}" + } + + $real_source = $source ? { + 'absent' => "puppet:///modules/nagios/plugins/${name}", + default => "puppet:///modules/${source}" + } + + file{$name: + ensure => $ensure, + path => $real_path, + source => $real_source, + tag => 'nagios_plugin', + require => Package['nagios-plugins'], + owner => 'root', + group => 0, + mode => '0755'; + } +} diff --git a/puppet/modules/nagios/manifests/plugin/deploy.pp b/puppet/modules/nagios/manifests/plugin/deploy.pp new file mode 100644 index 00000000..76815909 --- /dev/null +++ b/puppet/modules/nagios/manifests/plugin/deploy.pp @@ -0,0 +1,41 @@ +# deploy a specific plugin +define nagios::plugin::deploy( + $source = '', + $ensure = 'present', + $config = '', + $require_package = 'nagios-plugins' +) { + $plugin_src = $ensure ? { + 'present' => $name, + 'absent' => $name, + default => $ensure + } + $real_source = $source ? { + '' => "nagios/plugins/${plugin_src}", + default => $source + } + + if !defined(Package[$require_package]) { + package { $require_package: + ensure => installed, + tag => 'nagios::plugin::deploy::package'; + } + } + + include ::nagios::plugin::scriptpaths + file{"nagios_plugin_${name}": + path => "${nagios::plugin::scriptpaths::script_path}/${name}", + source => "puppet:///modules/${real_source}", + require => Package[$require_package], + tag => 'nagios::plugin::deploy::file', + owner => root, + group => 0, + mode => '0755'; + } + + # register the plugin + nagios::plugin{$name: + ensure => $ensure, + require => Package['nagios-plugins'] + } +} diff --git a/puppet/modules/nagios/manifests/plugin/scriptpaths.pp b/puppet/modules/nagios/manifests/plugin/scriptpaths.pp new file mode 100644 index 00000000..9cd4b5d6 --- /dev/null +++ b/puppet/modules/nagios/manifests/plugin/scriptpaths.pp @@ -0,0 +1,6 @@ +class nagios::plugin::scriptpaths { + case $::hardwaremodel { + x86_64: { $script_path = "/usr/lib64/nagios/plugins/" } + default: { $script_path = "/usr/lib/nagios/plugins" } + } +} diff --git a/puppet/modules/nagios/manifests/plugins/gpg.pp b/puppet/modules/nagios/manifests/plugins/gpg.pp new file mode 100644 index 00000000..a09736a8 --- /dev/null +++ b/puppet/modules/nagios/manifests/plugins/gpg.pp @@ -0,0 +1,30 @@ +# check_gpg from +# https://github.com/lelutin/nagios-plugins/blob/master/check_gpg +class nagios::plugins::gpg { + require ::gpg + nagios::plugin{'check_gpg': + source => 'nagios/plugins/check_gpg', + } + + $gpg_home = '/var/local/nagios_gpg_homedir' + file{ + $gpg_home: + ensure => 'directory', + owner => nagios, + group => nagios, + mode => '0600', + require => Nagios::Plugin['check_gpg']; + "${gpg_home}/sks-keyservers.netCA.pem": + source => 'puppet:///modules/nagios/plugin_data/sks-keyservers.netCA.pem', + owner => nagios, + group => 0, + mode => '0400', + before => Nagios_command['check_gpg']; + } + nagios_command { + 'check_gpg': + command_line => "\$USER1\$/check_gpg --gnupg-homedir ${gpg_home} -w \$ARG1\$ \$ARG2\$", + require => Nagios::Plugin['check_gpg'], + } +} + diff --git a/puppet/modules/nagios/manifests/plugins/horde_login.pp b/puppet/modules/nagios/manifests/plugins/horde_login.pp new file mode 100644 index 00000000..4274b4cf --- /dev/null +++ b/puppet/modules/nagios/manifests/plugins/horde_login.pp @@ -0,0 +1,11 @@ +# check_horde_login +class nagios::plugins::horde_login { + ensure_packages(['python-requests']) + nagios::plugin { 'check_horde_login': + source => 'nagios/plugins/check_horde_login', + require => Package['python-requests'], + } -> nagios_command { + 'check_horde_login': + command_line => "\$USER1\$/check_horde_login -s \$ARG1\$ -u \$ARG2\$ -p \$ARG3\$", + } +} diff --git a/puppet/modules/nagios/manifests/plugins/jabber.pp b/puppet/modules/nagios/manifests/plugins/jabber.pp new file mode 100644 index 00000000..380a5c0a --- /dev/null +++ b/puppet/modules/nagios/manifests/plugins/jabber.pp @@ -0,0 +1,10 @@ +class nagios::plugins::jabber { + + # for check_jabber_login + require rubygems::xmpp4r + + nagios::plugin { 'check_jabber_login': + source => 'nagios/plugins/check_jabber_login' + } +} + diff --git a/puppet/modules/nagios/manifests/plugins/mail_login.pp b/puppet/modules/nagios/manifests/plugins/mail_login.pp new file mode 100644 index 00000000..a86cdc24 --- /dev/null +++ b/puppet/modules/nagios/manifests/plugins/mail_login.pp @@ -0,0 +1,10 @@ +# simple mail login check +class nagios::plugins::mail_login { + nagios::plugin { + 'check_imap_login': + source => 'nagios/plugins/check_imap_login'; + 'check_pop3_login': + source => 'nagios/plugins/check_pop3_login'; + } +} + diff --git a/puppet/modules/nagios/manifests/pnp4nagios.pp b/puppet/modules/nagios/manifests/pnp4nagios.pp new file mode 100644 index 00000000..bd7ab0ca --- /dev/null +++ b/puppet/modules/nagios/manifests/pnp4nagios.pp @@ -0,0 +1,68 @@ +# manage pnp4nagios +class nagios::pnp4nagios { + include nagios::defaults::pnp4nagios + + package { [ 'pnp4nagios', 'pnp4nagios-web-config-nagios3']: + ensure => installed, + require => Package['nagios'] + } + + # unfortunatly we can't use the nagios_host and nagios_service + # definition to define templates, so we need to copy a file here. + # see http://projects.reductivelabs.com/issues/1180 for this limitation + + file { 'pnp4nagios-templates.cfg': + path => "${nagios::defaults::vars::int_cfgdir}/pnp4nagios-templates.cfg", + source => [ 'puppet:///modules/site_nagios/pnp4nagios/pnp4nagios-templates.cfg', + 'puppet:///modules/nagios/pnp4nagios/pnp4nagios-templates.cfg' ], + mode => '0644', + owner => root, + group => root, + notify => Service['nagios'], + require => Package['nagios']; + } + + file { 'apache.conf': + path => '/etc/pnp4nagios/apache.conf', + source => ['puppet:///modules/site_nagios/pnp4nagios/apache.conf', + 'puppet:///modules/nagios/pnp4nagios/apache.conf' ], + mode => '0644', + owner => root, + group => root, + notify => Service['apache'], + require => [ Package['apache2'], Package['pnp4nagios'] ], + } + + # run npcd as daemon + + file { '/etc/default/npcd': + path => '/etc/default/npcd', + source => [ 'puppet:///modules/site_nagios/pnp4nagios/npcd', + 'puppet:///modules/nagios/pnp4nagios/npcd' ], + mode => '0644', + owner => root, + group => root, + notify => Service['npcd'], + require => [ Package['nagios'], Package['pnp4nagios'] ]; + } + + service { 'npcd': + ensure => running, + enable => true, + hasstatus => true, + require => Package['pnp4nagios'], + } + + # modify action.gif + + file { '/usr/share/nagios3/htdocs/images/action.gif': + path => '/usr/share/nagios3/htdocs/images/action.gif', + source => [ 'puppet:///modules/site_nagios/pnp4nagios/action.gif', + 'puppet:///modules/nagios/pnp4nagios/action.gif' ], + mode => '0644', + owner => root, + group => root, + notify => Service['nagios'], + require => Package['nagios']; + } +} diff --git a/puppet/modules/nagios/manifests/pnp4nagios/popup.pp b/puppet/modules/nagios/manifests/pnp4nagios/popup.pp new file mode 100644 index 00000000..91136ccb --- /dev/null +++ b/puppet/modules/nagios/manifests/pnp4nagios/popup.pp @@ -0,0 +1,24 @@ +class nagios::pnp4nagios::popup inherits nagios::pnp4nagios { + File['pnp4nagios-templates.cfg']{ + source => [ + 'puppet:///modules/site-nagios/pnp4nagios/pnp4nagios-popup-templates.cfg', + 'puppet:///modules/nagios/pnp4nagios/pnp4nagios-popup-templates.cfg' ], + } + + file { '/usr/share/nagios3/htdocs/ssi': + ensure => directory, + require => Package['nagios'], + } + + file { 'status-header.ssi': + path => '/usr/share/nagios3/htdocs/ssi/status-header.ssi', + source => [ + 'puppet:///modules/site-nagios/pnp4nagios/status-header.ssi', + 'puppet:///modules/nagios/pnp4nagios/status-header.ssi'], + mode => '0644', + owner => root, + group => root, + notify => Service['nagios'], + require => Package['nagios'], + } +} diff --git a/puppet/modules/nagios/manifests/service.pp b/puppet/modules/nagios/manifests/service.pp new file mode 100644 index 00000000..e2c08e99 --- /dev/null +++ b/puppet/modules/nagios/manifests/service.pp @@ -0,0 +1,91 @@ +# a wrapper around nagios_service to make it more convenient and +# also automatically an exported resource. +define nagios::service ( + $ensure = present, + $host_name = $::fqdn, + $check_command = 'absent', + $check_period = undef, + $check_interval = undef, + $retry_check_interval = undef, + $max_check_attempts = undef, + $notification_interval = undef, + $notification_period = undef, + $notification_options = undef, + $contact_groups = undef, + $use = 'generic-service', + $service_description = 'absent', + $use_nrpe = undef, + $nrpe_args = undef, + $nrpe_timeout = 10, +) { + + # TODO: this resource should normally accept all nagios_host parameters + + $real_name = "${::hostname}_${name}" + + @@nagios_service {$real_name: + ensure => $ensure, + notify => Service['nagios']; + } + + if $ensure != 'absent' { + if $check_command == 'absent' { + fail("Must pass a check_command to ${name} if it should be present") + } + if str2bool($use_nrpe) { + include ::nagios::command::nrpe_timeout + + if $nrpe_args { + $real_check_command = "check_nrpe_timeout!${nrpe_timeout}!${check_command}!\"${nrpe_args}\"" + } else { + $real_check_command = "check_nrpe_1arg_timeout!${nrpe_timeout}!${check_command}" + } + } else { + $real_check_command = $check_command + } + + $real_service_description = $service_description ? { + 'absent' => $name, + default => $service_description + } + Nagios_service[$real_name] { + check_command => $check_command, + host_name => $host_name, + use => $use, + service_description => $real_service_description, + } + + if $check_period { + Nagios_service[$real_name] { check_period => $check_period } + } + + if $check_interval { + Nagios_service[$real_name] { check_interval => $check_interval } + } + + if $retry_check_interval { + Nagios_service[$real_name] { retry_check_interval => $retry_check_interval } + } + + if $max_check_attempts { + Nagios_service[$real_name] { max_check_attempts => $max_check_attempts } + } + + if $notification_interval { + Nagios_service[$real_name] { notification_interval => $notification_interval } + } + + if $notification_period { + Nagios_service[$real_name] { notification_period => $notification_period } + } + + if $notification_options { + Nagios_service[$real_name] { notification_options => $notification_options } + } + + if $contact_groups { + Nagios_service[$real_name] { contact_groups => $contact_groups } + } + } +} + diff --git a/puppet/modules/nagios/manifests/service/dns.pp b/puppet/modules/nagios/manifests/service/dns.pp new file mode 100644 index 00000000..5ef6e3e8 --- /dev/null +++ b/puppet/modules/nagios/manifests/service/dns.pp @@ -0,0 +1,19 @@ +define nagios::service::dns( + $host_name = $::fqdn, + $comment = $name, + $check_domain = $name, + $ip +){ + if $name != $comment { + $check_name = "${comment}_${name}_${::hostname}" + } else { + $check_name = "${name}_${::hostname}" + } + + nagios::service{ + $check_name: + check_command => "check_dns2!${check_domain}!${ip}", + host_name => $host_name, + service_description => "check if ${::host_name} is resolving ${check_domain}"; + } +} diff --git a/puppet/modules/nagios/manifests/service/dns_host.pp b/puppet/modules/nagios/manifests/service/dns_host.pp new file mode 100644 index 00000000..d88f3735 --- /dev/null +++ b/puppet/modules/nagios/manifests/service/dns_host.pp @@ -0,0 +1,22 @@ +# add a special host and monitor +# it's dns service +define nagios::service::dns_host( + $check_domain, + $host_alias, + $parent, + $ip +){ + @@nagios_host{$name: + address => $ip, + alias => $host_alias, + use => 'generic-host', + parents => $parent, + } + + nagios::service::dns{$name: + host_name => $name, + comment => 'public_ns', + check_domain => $check_domain, + ip => $ip, + } +} diff --git a/puppet/modules/nagios/manifests/service/gpgkey.pp b/puppet/modules/nagios/manifests/service/gpgkey.pp new file mode 100644 index 00000000..df13ca88 --- /dev/null +++ b/puppet/modules/nagios/manifests/service/gpgkey.pp @@ -0,0 +1,49 @@ +# define a gpgkey to be watched +define nagios::service::gpgkey( + $ensure = 'present', + $warning = '14', + $key_info = undef, + $check_interval = 60, +){ + validate_slength($name,40,40) + require ::nagios::plugins::gpg + $gpg_home = $nagios::plugins::gpg::gpg_home + $gpg_cmd = "gpg --homedir ${gpg_home}" + + exec{"manage_key_${name}": + user => nagios, + group => nagios, + } + nagios::service{ + "check_gpg_${name}": + ensure => $ensure; + } + + if $ensure == 'present' { + Exec["manage_key_${name}"]{ + command => "${gpg_cmd} --keyserver hkps://hkps.pool.sks-keyservers.net --keyserver-options ca-cert-file=${gpg_home}/sks-keyservers.netCA.pem --recv-keys ${name}", + unless => "${gpg_cmd} --list-keys ${name}", + before => Nagios::Service["check_gpg_${name}"], + } + + Nagios::Service["check_gpg_${name}"]{ + check_command => "check_gpg!${warning}!${name}", + check_interval => $check_interval, + } + if $key_info { + Nagios::Service["check_gpg_${name}"]{ + service_description => "Keyfingerprint: ${name} - Info: ${key_info}", + } + } else { + Nagios::Service["check_gpg_${name}"]{ + service_description => "Keyfingerprint: ${name}", + } + } + } else { + Exec["manage_key_${name}"]{ + command => "${gpg_cmd} --batch --delete-key ${name}", + onlyif => "${gpg_cmd} --list-keys ${name}", + require => Nagios::Service["check_gpg_${name}"], + } + } +} diff --git a/puppet/modules/nagios/manifests/service/horde_login.pp b/puppet/modules/nagios/manifests/service/horde_login.pp new file mode 100644 index 00000000..6cab59e9 --- /dev/null +++ b/puppet/modules/nagios/manifests/service/horde_login.pp @@ -0,0 +1,18 @@ +# a horde login check +define nagios::service::horde_login( + $password, + $url, + $username = $name, + $ensure = 'present', +){ + nagios::service{ + "horde_${name}": + ensure => $ensure; + } + + if $ensure != 'absent' { + Nagios::Service["horde_${name}"]{ + check_command => "check_horde_login!${url}!${username}!${password}", + } + } +} diff --git a/puppet/modules/nagios/manifests/service/http.pp b/puppet/modules/nagios/manifests/service/http.pp new file mode 100644 index 00000000..b80c140e --- /dev/null +++ b/puppet/modules/nagios/manifests/service/http.pp @@ -0,0 +1,54 @@ +# ssl_mode: +# - false: only check http +# - true: check http and https +# - force: http is permanent redirect to https +# - only: check only https +define nagios::service::http( + $ensure = present, + $check_domain = 'absent', + $port = '80', + $check_url = '/', + $check_code = '200,301,302', + $use = 'generic-service', + $ssl_mode = false +){ + $real_check_domain = $check_domain ? { + 'absent' => $name, + default => $check_domain + } + if is_hash($check_code) { + $check_code_hash = $check_code + } else { + $check_code_hash = { + http => $check_code, + https => $check_code, + } + } + case $ssl_mode { + 'force',true,'only': { + nagios::service{"https_${name}": + ensure => $ensure, + use => $use, + check_command => "check_https_url_regex!${real_check_domain}!${check_url}!'${check_code_hash[https]}'", + } + case $ssl_mode { + 'force': { + nagios::service{"http_${name}": + ensure => $ensure, + use => $use, + check_command => "check_http_url_regex!${real_check_domain}!${port}!${check_url}!'301'", + } + } + } + } + } + case $ssl_mode { + false,true: { + nagios::service{"http_${name}": + ensure => $ensure, + use => $use, + check_command => "check_http_url_regex!${real_check_domain}!${port}!${check_url}!'${check_code_hash[http]}'", + } + } + } +} diff --git a/puppet/modules/nagios/manifests/service/imap.pp b/puppet/modules/nagios/manifests/service/imap.pp new file mode 100644 index 00000000..45b667ab --- /dev/null +++ b/puppet/modules/nagios/manifests/service/imap.pp @@ -0,0 +1,34 @@ +# check an imap service +define nagios::service::imap( + $ensure = 'present', + $host = 'absent', + $port = '143', + $tls = true, + $tls_port = '993' +){ + + $real_host = $host ? { + 'absent' => $name, + default => $host + } + + $tls_ensure = $tls ? { + true => $ensure, + default => 'absent' + } + nagios::service{ + "imap_${name}_${port}": + ensure => $ensure; + "imaps_${name}_${tls_port}": + ensure => $tls_ensure; + } + + if $ensure != 'absent' { + Nagios::Service["imap_${name}_${port}"]{ + check_command => "check_imap!${real_host}!${port}", + } + Nagios::Service["imaps_${name}_${tls_port}"]{ + check_command => "check_imap_ssl!${real_host}!${tls_port}", + } + } +} diff --git a/puppet/modules/nagios/manifests/service/imap_login.pp b/puppet/modules/nagios/manifests/service/imap_login.pp new file mode 100644 index 00000000..25303a3f --- /dev/null +++ b/puppet/modules/nagios/manifests/service/imap_login.pp @@ -0,0 +1,22 @@ +# a imap login check +define nagios::service::imap_login( + $username, + $password, + $warning = 5, + $critical = 10, + $host = $::fqdn, + $host_name = $::fqdn, + $ensure = 'present', +){ + nagios::service{ + "imap_login_${name}": + ensure => $ensure; + } + + if $ensure != 'absent' { + Nagios::Service["imap_login_${name}"]{ + check_command => "check_imap_login!${host}!${username}!${password}!${warning}!${critical}", + host_name => $host_name, + } + } +} diff --git a/puppet/modules/nagios/manifests/service/mysql.pp b/puppet/modules/nagios/manifests/service/mysql.pp new file mode 100644 index 00000000..9559b17c --- /dev/null +++ b/puppet/modules/nagios/manifests/service/mysql.pp @@ -0,0 +1,58 @@ +# Checks a mysql instance via tcp or socket +define nagios::service::mysql( + $ensure = present, + $check_host = 'absent', + $check_port = '3306', + $check_username = 'nagios', + $check_password, + $check_database = 'information_schema', + $check_warning = undef, + $check_critical = undef, + $check_health_mode = $name, + $check_name = undef, + $check_name2 = undef, + $check_regexp = undef, + $check_units = undef, + $check_mode = 'tcp' ) +{ + + if ($check_host == 'absent') { + fail("Please specify a hostname, ip address or socket to check a mysql instance.") + } + + if $check_name != undef { + $real_check_name = "!--name $check_name" + } + + if $check_warning != undef { + $real_check_warning = "!--warning $check_warning" + } + + if $check_critical != undef { + $real_check_critical = "!--critical $check_critical" + } + + case $check_mode { + 'tcp': { + if ($check_host == 'localhost') { + $real_check_host = '127.0.0.1' + } + else { + $real_check_host = $check_host + } + } + default: { + if ($check_host == '127.0.0.1') { + $real_check_host = 'localhost' + } + else { + $real_check_host = $check_host + } + } + } + + nagios::service { "mysql_health_${name}": + ensure => $ensure, + check_command => "check_mysql_health!${real_check_host}!${check_port}!${check_username}!'${check_password}'!${check_health_mode}!${check_database}${real_check_name}${real_check_warning}${real_check_critical}", + } +} diff --git a/puppet/modules/nagios/manifests/service/ntp.pp b/puppet/modules/nagios/manifests/service/ntp.pp new file mode 100644 index 00000000..b3cde2ab --- /dev/null +++ b/puppet/modules/nagios/manifests/service/ntp.pp @@ -0,0 +1,9 @@ +# manifests/service/ntp.pp + +class nagios::service::ntp { + nagios::service{ "check_ntp": + check_command => "check_ntp_time", + host_name => $::fqdn, + } +} + diff --git a/puppet/modules/nagios/manifests/service/passive.pp b/puppet/modules/nagios/manifests/service/passive.pp new file mode 100644 index 00000000..f3df1e8b --- /dev/null +++ b/puppet/modules/nagios/manifests/service/passive.pp @@ -0,0 +1,18 @@ +define nagios::service::passive( + $ensure = present, + $notification_interval = '', + $notification_period = '', + $notification_options = '', + $contact_groups = '' +) { + + nagios::service { $name: + use => 'passive-service', + check_command => 'check_dummy!0', + notification_interval => $notification_interval, + notification_period => $notification_period, + notification_options => $notification_options, + contact_groups => $contact_groups, + } + +} diff --git a/puppet/modules/nagios/manifests/service/ping.pp b/puppet/modules/nagios/manifests/service/ping.pp new file mode 100644 index 00000000..f1c8d878 --- /dev/null +++ b/puppet/modules/nagios/manifests/service/ping.pp @@ -0,0 +1,9 @@ +define nagios::service::ping( + $ensure = present, + $ping_rate = '!100.0,20%!500.0,60%' +){ + nagios::service{ "check_ping": + ensure => $ensure, + check_command => "check_ping${ping_rate}", + } +} diff --git a/puppet/modules/nagios/manifests/service/pop.pp b/puppet/modules/nagios/manifests/service/pop.pp new file mode 100644 index 00000000..9ec4aec1 --- /dev/null +++ b/puppet/modules/nagios/manifests/service/pop.pp @@ -0,0 +1,32 @@ +define nagios::service::pop( + $ensure = 'present', + $host = 'absent', + $port = '110', + $tls = true, + $tls_port = '995' +){ + + $real_host = $host ? { + 'absent' => $name, + default => $host + } + + nagios::service{ + "pop_${name}_${port}": + ensure => $ensure; + "pops_${name}_${tls_port}": + ensure => $tls ? { + true => $ensure, + default => 'absent' + }; + } + + if $ensure != 'absent' { + Nagios::Service["pop_${name}_${port}"]{ + check_command => "check_pop3!${real_host}!${port}", + } + Nagios::Service["pops_${name}_${tls_port}"]{ + check_command => "check_pop3_ssl!${real_host}!${tls_port}", + } + } +} diff --git a/puppet/modules/nagios/manifests/service/pop3_login.pp b/puppet/modules/nagios/manifests/service/pop3_login.pp new file mode 100644 index 00000000..74535289 --- /dev/null +++ b/puppet/modules/nagios/manifests/service/pop3_login.pp @@ -0,0 +1,22 @@ +# a pop3 login check +define nagios::service::pop3_login( + $username, + $password, + $warning = 5, + $critical = 10, + $host = $::fqdn, + $host_name = $::fqdn, + $ensure = 'present', +){ + nagios::service{ + "pop3_login_${name}": + ensure => $ensure; + } + + if $ensure != 'absent' { + Nagios::Service["pop3_login_${name}"]{ + check_command => "check_pop3_login!${host}!${username}!${password}!${warning}!${critical}", + host_name => $host_name, + } + } +} diff --git a/puppet/modules/nagios/manifests/service/smtp.pp b/puppet/modules/nagios/manifests/service/smtp.pp new file mode 100644 index 00000000..14237a9e --- /dev/null +++ b/puppet/modules/nagios/manifests/service/smtp.pp @@ -0,0 +1,50 @@ +# true: +# - true : check tls and plain connect *defualt* +# - false : check plain connection only +# cert_days: +# If tls is used add an additionl check +# to check for validity for cert. +# - 'absent' : do not execute that check +# - INTEGER : Minimum number of days a certificate +# has to be valid. Default: 10 +define nagios::service::smtp( + $ensure = 'present', + $host = 'absent', + $port = '25', + $tls = true, + $cert_days = 10 +){ + $real_host = $host ? { + 'absent' => $name, + default => $host + } + + nagios::service{ + "smtp_${name}_${port}": + ensure => $ensure; + "smtp_tls_${name}_${port}": + ensure => $tls ? { + true => $ensure, + default => 'absent' + }; + "smtp_tls_cert_${name}_${port}": + ensure => $cert_days ? { + 'absent' => 'absent', + default => $ensure + }; + } + + if $ensure != 'absent' { + Nagios::Service["smtp_${name}_${port}"]{ + check_command => "check_smtp!${real_host}!${port}", + } + Nagios::Service["smtp_tls_${name}_${port}"]{ + check_command => "check_smtp_tls!${real_host}!${port}", + } + if $cert_days != 'absent' { + Nagios::Service["smtp_tls_cert_${name}_${port}"]{ + check_command => "check_smtp_cert!${real_host}!${port}!${cert_days}", + } + } + } +} diff --git a/puppet/modules/nagios/manifests/service/ssmtp.pp b/puppet/modules/nagios/manifests/service/ssmtp.pp new file mode 100644 index 00000000..b05678a6 --- /dev/null +++ b/puppet/modules/nagios/manifests/service/ssmtp.pp @@ -0,0 +1,32 @@ +define nagios::service::ssmtp( + $ensure = 'present', + $host = 'absent', + $port = '465', + $cert_days = 10 +){ + $real_host = $host ? { + 'absent' => $name, + default => $host + } + + nagios::service{ + "ssmtp_${name}_${port}": + ensure => $ensure; + "ssmtp_cert_${name}_${port}": + ensure => $cert_days ? { + 'absent' => 'absent', + default => $ensure + }; + } + + if $ensure != 'absent' { + Nagios::Service["ssmtp_${name}_${port}"]{ + check_command => "check_ssmtp!${real_host}!${port}", + } + if $cert_days != 'absent' { + Nagios::Service["ssmtp_cert_${name}_${port}"]{ + check_command => "check_ssmtp_cert!${real_host}!${port}!${cert_days}", + } + } + } +} diff --git a/puppet/modules/nagios/manifests/storeconfigs.pp b/puppet/modules/nagios/manifests/storeconfigs.pp new file mode 100644 index 00000000..96c30dd5 --- /dev/null +++ b/puppet/modules/nagios/manifests/storeconfigs.pp @@ -0,0 +1,61 @@ +# collect exported resources when using 'storeconfigs => true' +class nagios::storeconfigs { + + Nagios_command <<||>> + Nagios_contactgroup <<||>> + Nagios_contact <<||>> + Nagios_hostdependency <<||>> + Nagios_hostescalation <<||>> + Nagios_hostextinfo <<||>> + Nagios_hostgroup <<||>> + Nagios_host <<||>> + Nagios_servicedependency <<||>> + Nagios_serviceescalation <<||>> + Nagios_servicegroup <<||>> + Nagios_serviceextinfo <<||>> + Nagios_service <<||>> + Nagios_timeperiod <<||>> + + Nagios_command <||> { + notify => Service['nagios'], + } + Nagios_contact <||> { + notify => Service['nagios'], + } + Nagios_contactgroup <||> { + notify => Service['nagios'], + } + Nagios_host <||> { + notify => Service['nagios'], + } + Nagios_hostdependency <||> { + notify => Service['nagios'], + } + Nagios_hostescalation <||> { + notify => Service['nagios'], + } + Nagios_hostextinfo <||> { + notify => Service['nagios'], + } + Nagios_hostgroup <||> { + notify => Service['nagios'], + } + Nagios_service <||> { + notify => Service['nagios'], + } + Nagios_servicegroup <||> { + notify => Service['nagios'], + } + Nagios_servicedependency <||> { + notify => Service['nagios'], + } + Nagios_serviceescalation <||> { + notify => Service['nagios'], + } + Nagios_serviceextinfo <||> { + notify => Service['nagios'], + } + Nagios_timeperiod <||> { + notify => Service['nagios'], + } +} diff --git a/puppet/modules/nagios/manifests/stored_config.pp b/puppet/modules/nagios/manifests/stored_config.pp new file mode 100644 index 00000000..5afda04f --- /dev/null +++ b/puppet/modules/nagios/manifests/stored_config.pp @@ -0,0 +1,19 @@ +class nagios::stored_config { + # collect exported resources + + Nagios_command <<||>> + Nagios_contactgroup <<||>> + Nagios_contact <<||>> + Nagios_hostdependency <<||>> + Nagios_hostescalation <<||>> + Nagios_hostextinfo <<||>> + Nagios_hostgroup <<||>> + Nagios_host <<||>> + Nagios_servicedependency <<||>> + Nagios_serviceescalation <<||>> + Nagios_servicegroup <<||>> + Nagios_serviceextinfo <<||>> + Nagios_service <<||>> + Nagios_timeperiod <<||>> + +} diff --git a/puppet/modules/nagios/manifests/target.pp b/puppet/modules/nagios/manifests/target.pp new file mode 100644 index 00000000..760d7d47 --- /dev/null +++ b/puppet/modules/nagios/manifests/target.pp @@ -0,0 +1,32 @@ +# a simple nagios target to monitor +class nagios::target( + $parents = 'absent', + $address = $::ipaddress, + $nagios_alias = false, + $hostgroups = 'absent', + $use = 'generic-host', +){ + @@nagios_host { $::fqdn: + address => $address, + use => $use, + } + # Watch out with using aliases: they need to be unique throughout *all* + # resources in a given host's catalogue. + if $nagios_alias { + Nagios_host[$::fqdn]{ + alias => $nagios_alias + } + } + + if ($parents != 'absent') { + Nagios_host[$::fqdn]{ + parents => $parents + } + } + + if ($hostgroups != 'absent') { + Nagios_host[$::fqdn]{ + hostgroups => $hostgroups + } + } +} diff --git a/puppet/modules/nagios/manifests/target/fqdn.pp b/puppet/modules/nagios/manifests/target/fqdn.pp new file mode 100644 index 00000000..31fc4b71 --- /dev/null +++ b/puppet/modules/nagios/manifests/target/fqdn.pp @@ -0,0 +1,12 @@ +# monitor a host by fqdn +class nagios::target::fqdn( + $address = $::fqdn, + $hostgroups = 'absent', + $parents = 'absent' +) { + class{'nagios::target': + address => $address, + hostgroups => $hostgroups, + parents => $parents + } +} diff --git a/puppet/modules/nagios/templates/irc_bot/CentOS/nagios-nsa.sh.erb b/puppet/modules/nagios/templates/irc_bot/CentOS/nagios-nsa.sh.erb new file mode 100644 index 00000000..0f9f87b4 --- /dev/null +++ b/puppet/modules/nagios/templates/irc_bot/CentOS/nagios-nsa.sh.erb @@ -0,0 +1,104 @@ +#!/bin/sh +# +# nagios-nsa - manage nagios irc bot +# +# chkconfig: - 99 01 +# description: Nagios Simple IRC Agent + +### BEGIN INIT INFO +# Provides: nagios-nsa +# Required-Start: $nagios +# Required-Stop: $nagios +# Default-Start: 2 3 4 5 +# Default-Stop: 1 6 0 +# Short-Description: Nagios Simple IRC Agent +### END INIT INFO + +# Source function library. +. /etc/rc.d/init.d/functions + +exec="/usr/local/bin/riseup-nagios-server.pl" +prog="nsa" +PIDFILE=<%= scope.lookupvar('nagios::irc_bot::real_nsa_pidfile') %> +SOCKFILE=<%= scope.lookupvar('nagios::irc_bot::real_nsa_socket') %> + +[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog + +lockfile=/var/lock/subsys/$prog +mkdir -p /var/run/nagios-nsa 2>/dev/null +chown nagios /var/run/nagios-nsa + +start() { + [ -x $exec ] || exit 5 + [ -f $config ] || exit 6 + echo -n $"Starting $prog: " + daemon --pidfile $PIDFILE --user nagios /usr/local/bin/riseup-nagios-server.pl + retval=$? + echo + [ $retval -eq 0 ] && touch $lockfile + return $retval +} + +stop() { + echo -n $"Stopping $prog: " + killproc -p $PIDFILE $prog + retval=$? + echo + [ $retval -eq 0 ] && rm -f $lockfile + return $retval +} + +restart() { + stop + start +} + +reload() { + restart +} + +force_reload() { + restart +} + +rh_status() { + # run checks to determine if the service is running or use generic status + status -p $PIDFILE $prog +} + +rh_status_q() { + rh_status >/dev/null 2>&1 +} + + +case "$1" in + start) + rh_status_q && exit 0 + $1 + ;; + stop) + rh_status_q || exit 0 + $1 + ;; + restart) + $1 + ;; + reload) + rh_status_q || exit 7 + $1 + ;; + force-reload) + force_reload + ;; + status) + rh_status + ;; + condrestart|try-restart) + rh_status_q || exit 0 + restart + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" + exit 2 +esac +exit $? diff --git a/puppet/modules/nagios/templates/irc_bot/Debian/nagios-nsa.sh.erb b/puppet/modules/nagios/templates/irc_bot/Debian/nagios-nsa.sh.erb new file mode 100644 index 00000000..43c0e794 --- /dev/null +++ b/puppet/modules/nagios/templates/irc_bot/Debian/nagios-nsa.sh.erb @@ -0,0 +1,72 @@ +#! /bin/sh + +### BEGIN INIT INFO +# Provides: nagios-nsa +# Required-Start: $remote_fs $syslog nagios3 +# Required-Stop: $remote_fs $syslog nagios3 +# Default-Start: 2 3 4 5 +# Default-Stop: 1 6 0 +# Short-Description: Nagios Simple IRC Agent +### END INIT INFO + +PIDFILE=<%= scope.lookupvar('nagios::irc_bot::real_nsa_pidfile') %> +SOCKFILE=<%= scope.lookupvar('nagios::irc_bot::real_nsa_socket') %> + +. /lib/lsb/init-functions + +start() { + log_daemon_msg "Starting nagios IRC bot" "nagios-nsa" + if start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --user nagios --chuid nagios --exec /usr/local/bin/riseup-nagios-server.pl; then + log_end_msg 0 + else + log_end_msg 1 + fi +} + +stop () { + log_daemon_msg "Stopping nagios IRC bot" "nagios-nsa" + if start-stop-daemon --stop --quiet --pidfile $PIDFILE; then + log_end_msg 0 + else + log_end_msg 1 + fi +} + +remove_socket() { + [ -e $SOCKFILE ] && rm $SOCKFILE +} + +cleanup() { + if [ -r $PIDFILE ]; then + ps -p `cat $PIDFILE` | grep -v 'PID' || { + echo "not running" + remove_socket + } + else + echo "no pid file" + remove_socket + fi +} + +case $1 +in + start) + cleanup + start + ;; + stop) + stop + ;; + restart) + stop + cleanup + start + ;; + status) + status_of_proc -p $PIDFILE /usr/local/bin/riseup-nagios-server.pl && exit 0 || exit $? + ;; + *) + log_action_msg "Usage: /etc/init.d/nagios-nsa {start|stop|restart|status}" + exit 1 +esac + diff --git a/puppet/modules/nagios/templates/irc_bot/nsa.cfg.erb b/puppet/modules/nagios/templates/irc_bot/nsa.cfg.erb new file mode 100644 index 00000000..c4091e8a --- /dev/null +++ b/puppet/modules/nagios/templates/irc_bot/nsa.cfg.erb @@ -0,0 +1,15 @@ +%Nsa = ( + 'socket' => '<%= scope.lookupvar('nagios::irc_bot::real_nsa_socket') %>', + 'server' => '<%= scope.lookupvar('nagios::irc_bot::nsa_server') %>', + 'port' => '<%= scope.lookupvar('nagios::irc_bot::nsa_port') %>', + 'nickname' => '<%= scope.lookupvar('nagios::irc_bot::nsa_nickname') %>', + 'password' => '<%= scope.lookupvar('nagios::irc_bot::nsa_password') %>', + # this needs libio-socket-ssl-perl + # doesn't actually works because Net::IRC is braindead and tries to use IO::Socket::SSL->read/write instead of the builtin print, see http://search.cpan.org/dist/IO-Socket-SSL/SSL.pm + #'SSL' => 0, + 'channel' => '<%= scope.lookupvar('nagios::irc_bot::nsa_channel') %>', + 'pidfile' => '<%= scope.lookupvar('nagios::irc_bot::real_nsa_pidfile') %>', # set to undef to disable + 'realname' => '<%= scope.lookupvar('nagios::irc_bot::nsa_realname') %>', + 'usenotices' => '<%= scope.lookupvar('nagios::irc_bot::nsa_usenotices') %>', + 'commandfile' => '<%= scope.lookupvar('nagios::irc_bot::real_nsa_commandfile') %>', +); diff --git a/puppet/modules/nagios/templates/nrpe/nrpe.cfg b/puppet/modules/nagios/templates/nrpe/nrpe.cfg new file mode 100644 index 00000000..d4ad9a4d --- /dev/null +++ b/puppet/modules/nagios/templates/nrpe/nrpe.cfg @@ -0,0 +1,203 @@ +############################################################################# +# Sample NRPE Config File +# Written by: Ethan Galstad (nagios@nagios.org) +# +# Last Modified: 02-23-2006 +# +# NOTES: +# This is a sample configuration file for the NRPE daemon. It needs to be +# located on the remote host that is running the NRPE daemon, not the host +# from which the check_nrpe client is being executed. +############################################################################# + + +# PID FILE +# The name of the file in which the NRPE daemon should write it's process ID +# number. The file is only written if the NRPE daemon is started by the root +# user and is running in standalone mode. + +pid_file=<%= @pid_file %> + + + +# PORT NUMBER +# Port number we should wait for connections on. +# NOTE: This must be a non-priviledged port (i.e. > 1024). +# NOTE: This option is ignored if NRPE is running under either inetd or xinetd + +server_port=5666 + + + +# SERVER ADDRESS +# Address that nrpe should bind to in case there are more than one interface +# and you do not want nrpe to bind on all interfaces. +# NOTE: This option is ignored if NRPE is running under either inetd or xinetd + +<%- if not @server_address.to_s.empty? then %> +server_address=<%= @server_address %> +<%- end %> + + +# NRPE USER +# This determines the effective user that the NRPE daemon should run as. +# You can either supply a username or a UID. +# +# NOTE: This option is ignored if NRPE is running under either inetd or xinetd + +nrpe_user=nagios + + + +# NRPE GROUP +# This determines the effective group that the NRPE daemon should run as. +# You can either supply a group name or a GID. +# +# NOTE: This option is ignored if NRPE is running under either inetd or xinetd + +nrpe_group=nagios + + + +# ALLOWED HOST ADDRESSES +# This is an optional comma-delimited list of IP address or hostnames +# that are allowed to talk to the NRPE daemon. +# +# Note: The daemon only does rudimentary checking of the client's IP +# address. I would highly recommend adding entries in your /etc/hosts.allow +# file to allow only the specified host to connect to the port +# you are running this daemon on. +# +# NOTE: This option is ignored if NRPE is running under either inetd or xinetd + +<%- if @allowed_hosts.to_s.empty? then %> +allowed_hosts=127.0.0.1 +<%- else %> +allowed_hosts=127.0.0.1,<%= @allowed_hosts %> +<%- end %> + +# COMMAND ARGUMENT PROCESSING +# This option determines whether or not the NRPE daemon will allow clients +# to specify arguments to commands that are executed. This option only works +# if the daemon was configured with the --enable-command-args configure script +# option. +# +# *** ENABLING THIS OPTION IS A SECURITY RISK! *** +# Read the SECURITY file for information on some of the security implications +# of enabling this variable. +# +# Values: 0=do not allow arguments, 1=allow command arguments + +dont_blame_nrpe=<%= @dont_blame %> + + +# COMMAND PREFIX +# This option allows you to prefix all commands with a user-defined string. +# A space is automatically added between the specified prefix string and the +# command line from the command definition. +# +# *** THIS EXAMPLE MAY POSE A POTENTIAL SECURITY RISK, SO USE WITH CAUTION! *** +# Usage scenario: +# Execute restricted commmands using sudo. For this to work, you need to add +# the nagios user to your /etc/sudoers. An example entry for alllowing +# execution of the plugins from might be: +# +# nagios ALL=(ALL) NOPASSWD: /usr/lib/nagios/plugins/ +# +# This lets the nagios user run all commands in that directory (and only them) +# without asking for a password. If you do this, make sure you don't give +# random users write access to that directory or its contents! + +# command_prefix=/usr/bin/sudo + + + +# DEBUGGING OPTION +# This option determines whether or not debugging messages are logged to the +# syslog facility. +# Values: 0=debugging off, 1=debugging on + +debug=0 + + + +# COMMAND TIMEOUT +# This specifies the maximum number of seconds that the NRPE daemon will +# allow plugins to finish executing before killing them off. + +command_timeout=60 + + + +# WEEK RANDOM SEED OPTION +# This directive allows you to use SSL even if your system does not have +# a /dev/random or /dev/urandom (on purpose or because the necessary patches +# were not applied). The random number generator will be seeded from a file +# which is either a file pointed to by the environment valiable $RANDFILE +# or $HOME/.rnd. If neither exists, the pseudo random number generator will +# be initialized and a warning will be issued. +# Values: 0=only seed from /dev/[u]random, 1=also seed from weak randomness + +#allow_weak_random_seed=1 + + + +# INCLUDE CONFIG FILE +# This directive allows you to include definitions from an external config file. + +#include=<somefile.cfg> + + + +# INCLUDE CONFIG DIRECTORY +# This directive allows you to include definitions from config files (with a +# .cfg extension) in one or more directories (with recursion). + +#include_dir=<somedirectory> +#include_dir=<someotherdirectory> +include_dir=<%= @cfg_dir %>/nrpe.d + + + +# COMMAND DEFINITIONS +# Command definitions that this daemon will run. Definitions +# are in the following format: +# +# command[<command_name>]=<command_line> +# +# When the daemon receives a request to return the results of <command_name> +# it will execute the command specified by the <command_line> argument. +# +# Unlike Nagios, the command line cannot contain macros - it must be +# typed exactly as it should be executed. +# +# Note: Any plugins that are used in the command lines must reside +# on the machine that this daemon is running on! The examples below +# assume that you have plugins installed in a /usr/local/nagios/libexec +# directory. Also note that you will have to modify the definitions below +# to match the argument format the plugins expect. Remember, these are +# examples only! + +# The following examples use hardcoded command arguments... + +#command[check_users]=/usr/lib/nagios/plugins/check_users -w 5 -c 10 +#command[check_load]=/usr/lib/nagios/plugins/check_load -w 15,10,5 -c 30,25,20 +#command[check_disk1]=/usr/lib/nagios/plugins/check_disk -w 20 -c 10 -p /dev/hda1 +#command[check_disk2]=/usr/lib/nagios/plugins/check_disk -w 20 -c 10 -p /dev/hdb1 +#command[check_zombie_procs]=/usr/lib/nagios/plugins/check_procs -w 5 -c 10 -s Z +#command[check_total_procs]=/usr/lib/nagios/plugins/check_procs -w 150 -c 200 + +# The following examples allow user-supplied arguments and can +# only be used if the NRPE daemon was compiled with support for +# command arguments *AND* the dont_blame_nrpe directive in this +# config file is set to '1'... + +#command[check_users]=/usr/lib/nagios/plugins/check_users -w $ARG1$ -c $ARG2$ +#command[check_load]=/usr/lib/nagios/plugins/check_load -w $ARG1$ -c $ARG2$ +#command[check_disk]=/usr/lib/nagios/plugins/check_disk -w $ARG1$ -c $ARG2$ -p $ARG3$ +#command[check_procs]=/usr/lib/nagios/plugins/check_procs -w $ARG1$ -c $ARG2$ -s $ARG3$ + +# +# local configuration: +# if you'd prefer, you can instead place directives here + diff --git a/puppet/modules/nagios/templates/nrpe/nrpe_command.erb b/puppet/modules/nagios/templates/nrpe/nrpe_command.erb new file mode 100644 index 00000000..99f4601b --- /dev/null +++ b/puppet/modules/nagios/templates/nrpe/nrpe_command.erb @@ -0,0 +1,2 @@ +# generated by puppet, do not edit +command[<%= name -%>]=<%= command_line %> |