forked from c3d2/nix-config
Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
012cb9639a | ||
|
56261a7bd7 | ||
|
e5d2d03f44 |
|
@ -1,9 +0,0 @@
|
|||
# This file contains a list of commits that are not likely what you
|
||||
# are looking for in a blame, such as mass reformatting or renaming.
|
||||
# You can set this file as a default ignore file for blame by running
|
||||
# the following command.
|
||||
#
|
||||
# $ git config blame.ignoreRevsFile .git-blame-ignore-revs
|
||||
|
||||
# big format
|
||||
aaddec81945750222721659be65ecd6bf2503c6a
|
183
.sops.yaml
183
.sops.yaml
|
@ -1,183 +0,0 @@
|
|||
keys:
|
||||
# The PGP keys in keys/
|
||||
- &admins
|
||||
- A5EE826D645DBE35F9B0993358512AE87A69900F # astro
|
||||
#- 270DAEB0EC5A129CE1F38E2FCB5009A2DB4C5190 # blastmaster
|
||||
- D4E89C6A0A58EE803EF708EFA9B23715F7AA3F1A # deployer
|
||||
#- 844267BA729E32B3329B9DBF59E238FC65F349F2 # eri
|
||||
- A4B0F5A80C2E2448A97BEC25BB829C4DECA6CCB9 # winzlieb
|
||||
#- 9580391316684474BFBD41EC3E8C55248C19AF2A # xyrill
|
||||
- 4F9F44A64CC2E438979329E1F122F05437696FCE # poelzi
|
||||
#- B2918084D9BA194C66AE78769E5D7AAA5B6B2D79 # schmittlauch?
|
||||
- 4B12EFA69166CA8C23FC47E49CD3A46248B660CA # vv01f
|
||||
- 9EA68B7F21204979645182E4287B083353C3241C # j03
|
||||
- 53B26AEDC08246715E15504B236B6291555E8401 # sandro
|
||||
- 91EBE87016391323642A6803B966009D57E69CC6 # revol-xut
|
||||
|
||||
- &polygon-snowflake age12aukzah0pt2rck52hwn08kezyxueqz2f49ld7hpyuzmu847vavdqkunn5c # polygon
|
||||
|
||||
# Generate AGE keys from SSH keys with:
|
||||
# nix shell nixpkgs#ssh-to-age
|
||||
# ssh-to-age < /etc/ssh/ssh_host_ed25519_key.pub
|
||||
- &auth age1y7lxpxskqclwqluft2ct2c3u8weehus6t8evwk7cdnpakxzgcquspn827x
|
||||
- &bind age1hfzpctkk5tz0ddc86ul9t0nf8c37jtngawepvgxk5rxlvv938vusx4kuc6
|
||||
- &blogs age1lccjvj9z8de4hfrdeumm9eu7awef4d9jygv3w7zdash3fhv6e53quy53wz
|
||||
- &broker age1dj0d0339f4law7qvuzcv2fs6sf8why63s3l8tja0f8vsj7wefcds9drvte
|
||||
- &c3d2-web age18h6vmfduhmj28wxdgur8wugn7scm5vwvwkj5sr4f7nl0czr2zvaqscsdsv
|
||||
- &dacbert age1hg0mmua5y82ct7l6q9gpc8w940ce5seqcjhm4dgx7tlzvflznyas7v3hf4
|
||||
- &direkthilfe age1qe8wvy8kdmfdxh505apkqnnquqgtvykd6x6qlxmzqp93cv6wjy4qlu5mpj
|
||||
- &dn42 age1726t33dl7pv3xrxxlafj2sexh7c0jm8pza84yu6l3wpz3fw5dauqxlass3
|
||||
- &factorio age1av4ww0zzyas0egzwkpdaj4crwz3vwnhpq0nfez2zad4me38zss7sjz5kw2
|
||||
- &freifunk age17rrjtdgzzwgjatyqqv27pftx42t8xhksls46jc3f78juzw4g04vsd7lr7e
|
||||
- &ftp age1lkr5rkf3z0976g8snmznf755gnexhjkwpzsw8xxwyesqmneawa4qgsqx77
|
||||
- &gitea age12n5k6c4rxp4mjnexw9uw83yp34sallt44kldupfmxr2xkppj8a8sdsmv8h
|
||||
- &glotzbert age1zqpep2vgfqeyvtj2jpxczfgrpjffwda429rnuztfp0vpqsrqdq8s8f4yua
|
||||
- &gnunet age1kk0thtx6mg5cs0gqm4ylc4r8w6klq660s3j04w7m8w0w084yrpcqh3tqwf
|
||||
- &grafana age1yahhqn2620300n20k68az5lr2u42wdgtjwysgqyr99a4cj52ay0qjw02pl
|
||||
- &hedgedoc age1jt5pj0c0fvmzg7quaucq4n2rzcx9ajzstp8ruwc8ewjpay5vqfqsdjaal8
|
||||
- &hydra age1px8sjpcmnz27ayczzu883n0p5ad34vnzj6rl9y2eyye546v0m3dqfqx459
|
||||
- &jabber age1tnq862ekxepjkes6efr282uj9gtcsqru04s5k0l2enq5djxyt5as0k0c2a
|
||||
- &leon age1cm0cjk2764s4pv5g7e67as34g9xtcltex96ga87wckndw62wqqlsvkscqc
|
||||
- &leoncloud age1aw9s4kcd6ys64ddzzfya9ajzln2tv8pm9uvz6d85v0r6eq4dudqq5vts86
|
||||
- &mailtngbert age1lgjvtszpds9flpwsstxdht00c7zlk3mz7nlc5qftyt8rhfdm330qqmhl72
|
||||
- &matemat age15vmz2evhnkn26fyt4vqvgztfrsr2s8qavd2m6zfjmkh84q2g75csnc5kr6
|
||||
- &mediawiki age1xjvep7hsnfefgxvuwall8nq0486qu8yknhzwhf0cskw5xlpm8qws9txc56
|
||||
- &mucbot age1cqeh03zq0hvz5l78r678q93ey5mlw49lqy4whvgqxgenudth7g6skee6kh
|
||||
- &nfsroot age18yxgwpakrkzq8ca2enayf79py25se3d8dsed2q523869re30jcaqx6rjln
|
||||
- &nncp age15853dr2kd6r2329tkcanwnruh6zd2xvsu5twc7gnxeyu3h7t6q5scckaq8
|
||||
- &oparl age14aq8fscrwkgmu5yv86vj7p7kmxclzs6dp7fpvdhvrnmce83ztphqc4mr9q
|
||||
- &public-access-proxy age1xcj6peyaf5xvj2673vl9j0z7supwtw7hzuk782zk7gt69k2ykytqe65mg5
|
||||
- &pulsebert age12hdk2stter0cjexxwx3sqn9wx3vmptkxszvx7knq9zgm9uqzjs7suvkcqu
|
||||
- &radiobert age1lga6hjmxa95fmtdn3frlmy64ej3hyswxrcuz25qvw0kfsxkqeugs8gjw8q
|
||||
- &riscbert age148d87gqw59lmst5jv3vynhsu3tv4t4sj49s4lktvnplfcrjq2y5sjcwsu8
|
||||
- &scrape age1p60rg45qrzpv2hcfzxl8d8k9afkk7dtrhr98cngeyuhlega83ynssmtx5k
|
||||
- &sdrweb age1makkpv2t74lxmw0nk6m89nespva7j700pmt83pl5a4ldtj2k8fzqakw8h7
|
||||
- &server9 age15vrlmtckjf4j242juw7l5e0s6eunn67ejr9acaztnl3tmvwpufrsevntva
|
||||
- &server10 age15qj8latetnrmgzd7krq02y65kn7lhq2pcwv8cvzej2783u5a9scqs79nmf
|
||||
- &spaceapi age125k9uyqw5ae5jqkfsak4d6c6rcx9q63ywuusk62pmxdnhwzqxgqq2jsau7
|
||||
- &stream age1j5csp5v5s2g8am47dd85kcke8986e0qc88f0vfgd3kmvwu8azg3smslk92
|
||||
- &storage-ng age1qjvds58pedjdk9rj0yqfvad4xhpteapr9chvfucwcgwrsr8n7axqyhg2vu
|
||||
- &ticker age1kdrpaqsy7gdnf80fpq6qrrc98nqjuzzlqx955uk2pkky3xcxky8sw9cdjl
|
||||
|
||||
creation_rules:
|
||||
- path_regex: config/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- pgp: *admins
|
||||
age:
|
||||
- *polygon-snowflake
|
||||
- *auth
|
||||
- *bind
|
||||
- *blogs
|
||||
- *broker
|
||||
- *c3d2-web
|
||||
- *dacbert
|
||||
- *direkthilfe
|
||||
- *dn42
|
||||
- *factorio
|
||||
- *freifunk
|
||||
- *ftp
|
||||
- *gitea
|
||||
- *glotzbert
|
||||
- *gnunet
|
||||
- *grafana
|
||||
- *hedgedoc
|
||||
- *hydra
|
||||
- *jabber
|
||||
- *leon
|
||||
- *leoncloud
|
||||
- *mailtngbert
|
||||
- *matemat
|
||||
- *mediawiki
|
||||
- *mucbot
|
||||
- *nfsroot
|
||||
- *oparl
|
||||
- *public-access-proxy
|
||||
- *pulsebert
|
||||
- *radiobert
|
||||
- *riscbert
|
||||
- *scrape
|
||||
- *sdrweb
|
||||
- *server9
|
||||
- *server10
|
||||
- *spaceapi
|
||||
- *stream
|
||||
- *storage-ng
|
||||
- *ticker
|
||||
- path_regex: hosts/auth/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- pgp: *admins
|
||||
age:
|
||||
- *auth
|
||||
- *polygon-snowflake
|
||||
- path_regex: hosts/blogs/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- pgp: *admins
|
||||
age:
|
||||
- *blogs
|
||||
- *polygon-snowflake
|
||||
- path_regex: hosts/broker/secrets\.yaml$
|
||||
key_groups:
|
||||
- pgp: *admins
|
||||
age:
|
||||
- *broker
|
||||
- *polygon-snowflake
|
||||
- path_regex: hosts/dn42/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- pgp: *admins
|
||||
age:
|
||||
- *dn42
|
||||
- *polygon-snowflake
|
||||
- path_regex: hosts/freifunk/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- pgp: *admins
|
||||
age:
|
||||
- *freifunk
|
||||
- *polygon-snowflake
|
||||
- path_regex: hosts/glotzbert/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- pgp: *admins
|
||||
age:
|
||||
- *glotzbert
|
||||
- *polygon-snowflake
|
||||
- path_regex: hosts/hedgedoc/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- pgp: *admins
|
||||
age:
|
||||
- *hedgedoc
|
||||
- *polygon-snowflake
|
||||
- path_regex: hosts/hydra/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- pgp: *admins
|
||||
age:
|
||||
- *hydra
|
||||
- *polygon-snowflake
|
||||
- path_regex: hosts/mailtngbert/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- pgp: *admins
|
||||
age:
|
||||
- *mailtngbert
|
||||
- *polygon-snowflake
|
||||
- path_regex: hosts/mediawiki/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- pgp: *admins
|
||||
age:
|
||||
- *mediawiki
|
||||
- *polygon-snowflake
|
||||
- path_regex: hosts/oparl/secrets\.yaml$
|
||||
key_groups:
|
||||
- pgp: *admins
|
||||
age:
|
||||
- *oparl
|
||||
- *polygon-snowflake
|
||||
- path_regex: hosts/radiobert/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- pgp: *admins
|
||||
age:
|
||||
- *radiobert
|
||||
- *polygon-snowflake
|
||||
- path_regex: hosts/storage-ng/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- pgp: *admins
|
||||
age:
|
||||
- *storage-ng
|
||||
- *polygon-snowflake
|
53
README.md
53
README.md
|
@ -34,6 +34,16 @@ Make sure you have access.
|
|||
|
||||
> Nix Flakes ist gegenwärtig bei Nix (Version 20.09) noch keine standardmäßige Funktionalität für Nix. Die Bereitstellung der Kommandos für Nix Flakes müssen als experimentelle Funktionalität für das Kommando ''nix'' festgelegt werden, um sie verfügbar zu machen.
|
||||
|
||||
A Nix environment with Nix Flakes support is required.
|
||||
|
||||
### Temporary Shell with Nix Flakes
|
||||
|
||||
Set up an environment (with the common command [nix-shell](https://nixos.org/manual/nix/unstable/command-ref/nix-shell.html)) in which the [package *nixFlakes*](https://search.nixos.org/packages?query=nixflakes) (for Nix Flakes) is available and jump into it
|
||||
|
||||
```bash
|
||||
nix-shell -p nixFlakes
|
||||
```
|
||||
|
||||
Set some configuration (do this only once):
|
||||
|
||||
```bash
|
||||
|
@ -46,6 +56,7 @@ set this to your NixOS configuration:
|
|||
```nix
|
||||
{ pkgs, ... }: {
|
||||
nix = {
|
||||
package = pkgs.nixFlakes;
|
||||
extraOptions = "experimental-features = nix-command flakes";
|
||||
};
|
||||
}
|
||||
|
@ -63,14 +74,14 @@ to update that machine to the current configuration and Nixpkgs revision.
|
|||
For every host that has a `nixosConfiguration` in our Flake, there are
|
||||
two scripts that can be run for deployment via ssh.
|
||||
|
||||
- `nix run .#glotzbert-nixos-rebuild switch`
|
||||
- `nix run c3d2#glotzbert-nixos-rebuild switch`
|
||||
|
||||
Copies the current state to build on the target system. This may
|
||||
fail due to eg. container resource limits.
|
||||
|
||||
The target must already be a nixFlakes system.
|
||||
|
||||
- `nix run .#glotzbert-nixos-rebuild-local switch`
|
||||
- `nix run c3d2#glotzbert-nixos-rebuild-local switch`
|
||||
|
||||
Builds locally, then uses `nix copy` to transfer the new NixOS
|
||||
system to the target.
|
||||
|
@ -79,6 +90,8 @@ two scripts that can be run for deployment via ssh.
|
|||
target? If so, use `nix copy` to transfer where
|
||||
`/run/current-system` points to to your build machine.
|
||||
|
||||
Use `nix flake show c3d2` to show what is available.
|
||||
|
||||
## Remote deployment from non-NixOS
|
||||
|
||||
A shell script that copies the current working tree, and runs
|
||||
|
@ -114,40 +127,10 @@ Just run:
|
|||
update-from-hydra
|
||||
```
|
||||
|
||||
## Deploy a MicroVM
|
||||
## Creating a new Proxmox container
|
||||
|
||||
### Building spaceapi remotely, and deploy
|
||||
|
||||
```shell
|
||||
nix run .#microvm-update-spaceapi
|
||||
```
|
||||
|
||||
### Building spaceapi locally, and deploy
|
||||
|
||||
```shell
|
||||
nix run .#microvm-update-spaceapi-local
|
||||
```
|
||||
|
||||
### Update MicroVM from our Hydra
|
||||
|
||||
Our Hydra runs `nix flake update` daily in the `updater.timer`,
|
||||
pushing it to the `flake-update` branch so that it can build fresh
|
||||
systems. This branch is setup as the source flake in all the MicroVMs,
|
||||
so the following is all that is needed on a MicroVM-hosting server:
|
||||
|
||||
```shell
|
||||
microvm -Ru $hostname
|
||||
```
|
||||
|
||||
## High Availability Deployment on Nomad
|
||||
|
||||
First, stop and delete `/var/lib/microvm/$NAME` where the
|
||||
systemd-managed MicroVMs live, or move the state to
|
||||
`/glusterfs/fast/microvms/$NAME`.
|
||||
|
||||
```sh
|
||||
nix run .#nomad-$NAME
|
||||
```
|
||||
Use the `nixprox.sh` script that should be copied to
|
||||
`/usr/local/sbin/nixprox.sh` on all of the Proxmox servers.
|
||||
|
||||
# Secrets management
|
||||
|
||||
|
|
5
ansible/ansible.cfg
Normal file
5
ansible/ansible.cfg
Normal file
|
@ -0,0 +1,5 @@
|
|||
[defaults]
|
||||
|
||||
# some basic default values...
|
||||
|
||||
inventory = ./hosts
|
21
ansible/hosts
Normal file
21
ansible/hosts
Normal file
|
@ -0,0 +1,21 @@
|
|||
[hypervisor]
|
||||
server3.hq.c3d2.de
|
||||
server5.hq.c3d2.de
|
||||
server6.hq.c3d2.de
|
||||
server7.hq.c3d2.de
|
||||
server8.hq.c3d2.de
|
||||
server9.hq.c3d2.de
|
||||
|
||||
[hypervisor:vars]
|
||||
ansible_connection=ssh
|
||||
ansible_user=root
|
||||
|
||||
[kubernetes]
|
||||
k8s-1.hq.c3d2.de
|
||||
k8s-2.hq.c3d2.de
|
||||
k8s-3.hq.c3d2.de
|
||||
k8s-4.hq.c3d2.de
|
||||
|
||||
[kubernetes:vars]
|
||||
ansible_python_interpreter=/usr/bin/python3
|
||||
ansible_user=ubuntu
|
57
ansible/hypervisor.yml
Normal file
57
ansible/hypervisor.yml
Normal file
|
@ -0,0 +1,57 @@
|
|||
---
|
||||
# file: hypervisor.yml
|
||||
- hosts: hypervisor
|
||||
roles:
|
||||
- proxmox
|
||||
- { role: "elastic.beats", beat: "filebeat",
|
||||
become: true,
|
||||
tags: ["filebeat", "logging"],
|
||||
beats_version: "7.12.1",
|
||||
beat_conf: {
|
||||
filebeat: {
|
||||
"inputs":[{
|
||||
"type": log,
|
||||
"enabled": true,
|
||||
"paths": [
|
||||
"/var/log/ceph/*.log",
|
||||
"/var/log/pve/tasks/*/*",
|
||||
"/var/log/vzdump/*.log",
|
||||
|
||||
],
|
||||
tags: ["hypervisor", "proxmox"]
|
||||
}]
|
||||
}
|
||||
},
|
||||
"output_conf": {
|
||||
"logstash": {
|
||||
"hosts": ["logging.serv.zentralwerk.org:5044", "172.20.73.13:5044"]
|
||||
}
|
||||
},
|
||||
logging_conf: {
|
||||
level: warning,
|
||||
to_files: false
|
||||
}
|
||||
}
|
||||
- { role: "elastic.beats", beat: "journalbeat",
|
||||
become: true,
|
||||
tags: ["journalbeat", "logging"],
|
||||
beats_version: "7.12.1",
|
||||
beat_conf: {
|
||||
journalbeat: {
|
||||
"inputs":[{
|
||||
seek: cursor,
|
||||
"paths": []
|
||||
}]
|
||||
},
|
||||
tags: ["hypervisor", "proxmox"]
|
||||
},
|
||||
"output_conf": {
|
||||
"logstash": {
|
||||
"hosts": ["logging.serv.zentralwerk.org:5044", "172.20.73.13:5044"]
|
||||
}
|
||||
},
|
||||
logging_conf: {
|
||||
level: warning,
|
||||
to_files: false,
|
||||
}
|
||||
}
|
19
ansible/kubernetes.yml
Normal file
19
ansible/kubernetes.yml
Normal file
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
# file: hypervisor.yml
|
||||
- hosts: kubernetes
|
||||
become: yes
|
||||
become_user: root
|
||||
become_method: sudo
|
||||
vars:
|
||||
check_mk_agent_over_ssh: False
|
||||
check_mk_agent_monitoring_host: monit.hq.c3d2.de
|
||||
check_mk_agent_monitoring_user: monitoring
|
||||
check_mk_agent_add_to_wato: False
|
||||
check_mk_agent_monitoring_host_wato_username: monitoring
|
||||
check_mk_agent_monitoring_host_url: https://monit.hq.c3d2.de/c3d2/
|
||||
# check_mk_agent_local_checks:
|
||||
# filecount:
|
||||
# src: files/check_mk_local_checks/filecount
|
||||
roles:
|
||||
- k8s
|
||||
- elnappo.check_mk_agent
|
58
ansible/roles/elastic.beats/.ci/jobs/defaults.yml
Normal file
58
ansible/roles/elastic.beats/.ci/jobs/defaults.yml
Normal file
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
|
||||
##### GLOBAL METADATA
|
||||
|
||||
- meta:
|
||||
cluster: devops-ci
|
||||
|
||||
##### JOB DEFAULTS
|
||||
|
||||
- job:
|
||||
project-type: matrix
|
||||
logrotate:
|
||||
daysToKeep: 30
|
||||
numToKeep: 100
|
||||
parameters:
|
||||
- string:
|
||||
name: branch_specifier
|
||||
default: master
|
||||
description: the Git branch specifier to build (<branchName>, <tagName>,
|
||||
<commitId>, etc.)
|
||||
properties:
|
||||
- github:
|
||||
url: https://github.com/elastic/ansible-beats/
|
||||
- inject:
|
||||
properties-content: HOME=$JENKINS_HOME
|
||||
concurrent: true
|
||||
node: master
|
||||
scm:
|
||||
- git:
|
||||
name: origin
|
||||
credentials-id: f6c7695a-671e-4f4f-a331-acdce44ff9ba
|
||||
reference-repo: /var/lib/jenkins/.git-references/ansible-beats.git
|
||||
branches:
|
||||
- ${branch_specifier}
|
||||
url: git@github.com:elastic/ansible-beats.git
|
||||
basedir: ansible-beats
|
||||
wipe-workspace: 'False'
|
||||
axes:
|
||||
- axis:
|
||||
type: slave
|
||||
name: label
|
||||
values:
|
||||
- linux
|
||||
- axis:
|
||||
name: OS
|
||||
filename: ansible-beats/test/matrix.yml
|
||||
type: yaml
|
||||
- axis:
|
||||
name: TEST_TYPE
|
||||
filename: ansible-beats/test/matrix.yml
|
||||
type: yaml
|
||||
wrappers:
|
||||
- ansicolor
|
||||
- timeout:
|
||||
type: absolute
|
||||
timeout: 360
|
||||
fail: true
|
||||
- timestamps
|
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
- job:
|
||||
name: elastic+ansible-beats+master
|
||||
display-name: elastic / ansible-beats - master
|
||||
description: Master branch testing with test kitchen
|
||||
triggers:
|
||||
- timed: H H(02-04) * * *
|
||||
builders:
|
||||
- shell: |-
|
||||
#!/usr/local/bin/runbld
|
||||
set -euo pipefail
|
||||
|
||||
export RBENV_VERSION='2.5.7'
|
||||
export PATH="$HOME/.rbenv/bin:$PATH"
|
||||
eval "$(rbenv init -)"
|
||||
rbenv local $RBENV_VERSION
|
||||
|
||||
make setup
|
||||
make verify PATTERN=$TEST_TYPE-$OS
|
||||
publishers:
|
||||
- slack:
|
||||
notify-back-to-normal: True
|
||||
notify-every-failure: True
|
||||
room: infra-release-notify
|
||||
team-domain: elastic
|
||||
auth-token-id: release-slack-integration-token
|
||||
auth-token-credential-id: release-slack-integration-token
|
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
- job:
|
||||
name: elastic+ansible-beats+pull-request
|
||||
display-name: elastic / ansible-beats - pull-request
|
||||
description: Pull request testing with test kitchen
|
||||
parameters: []
|
||||
scm:
|
||||
- git:
|
||||
branches:
|
||||
- $ghprbActualCommit
|
||||
refspec: +refs/pull/*:refs/remotes/origin/pr/*
|
||||
triggers:
|
||||
- github-pull-request:
|
||||
github-hooks: true
|
||||
org-list:
|
||||
- elastic
|
||||
allow-whitelist-orgs-as-admins: true
|
||||
cancel-builds-on-update: true
|
||||
status-context: devops-ci
|
||||
builders:
|
||||
- shell: |-
|
||||
#!/usr/local/bin/runbld
|
||||
set -euo pipefail
|
||||
|
||||
export RBENV_VERSION='2.5.7'
|
||||
export PATH="$HOME/.rbenv/bin:$PATH"
|
||||
eval "$(rbenv init -)"
|
||||
rbenv local $RBENV_VERSION
|
||||
|
||||
make setup
|
||||
make verify PATTERN=$TEST_TYPE-$OS
|
40
ansible/roles/elastic.beats/.github/issue_template.md
vendored
Normal file
40
ansible/roles/elastic.beats/.github/issue_template.md
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
<!--
|
||||
|
||||
** Please read the guidelines below. **
|
||||
|
||||
Issues that do not follow these guidelines are likely to be closed.
|
||||
|
||||
1. GitHub is reserved for bug reports and feature requests. The best place to
|
||||
ask a general question is at the Elastic [forums](https://discuss.elastic.co).
|
||||
GitHub is not the place for general questions.
|
||||
|
||||
2. Is this bug report or feature request for a supported OS? If not, it
|
||||
is likely to be closed. See https://www.elastic.co/support/matrix#show_os
|
||||
|
||||
3. Please fill out EITHER the feature request block or the bug report block
|
||||
below, and delete the other block.
|
||||
|
||||
-->
|
||||
|
||||
<!-- Feature request -->
|
||||
|
||||
**Describe the feature**:
|
||||
|
||||
<!-- Bug report -->
|
||||
|
||||
**Beats product**:
|
||||
|
||||
**Beats version**
|
||||
|
||||
**Role version**: (If using master please specify github sha)
|
||||
|
||||
**OS version** (`uname -a` if on a Unix-like system):
|
||||
|
||||
**Description of the problem including expected versus actual behaviour**:
|
||||
|
||||
**Playbook**:
|
||||
Please specify the full playbook used to reproduce this issue.
|
||||
|
||||
**Provide logs from Ansible**:
|
||||
|
||||
**Beats logs if relevant**:
|
35
ansible/roles/elastic.beats/.github/stale.yml
vendored
Normal file
35
ansible/roles/elastic.beats/.github/stale.yml
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 90
|
||||
|
||||
# Number of days of inactivity before an stale issue is closed
|
||||
daysUntilClose: 30
|
||||
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: triage/stale
|
||||
|
||||
issues:
|
||||
# Comment to post when marking an issue as stale.
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank
|
||||
you for your contributions.
|
||||
# Comment to post when closing a stale issue.
|
||||
closeComment: >
|
||||
This issue has been automatically closed because it has not had recent
|
||||
activity since being marked as stale.
|
||||
pulls:
|
||||
# Comment to post when marking a PR as stale.
|
||||
markComment: >
|
||||
This PR has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
|
||||
To track this PR (even if closed), please open a corresponding issue if one
|
||||
does not already exist.
|
||||
# Comment to post when closing a stale PR.
|
||||
closeComment: >
|
||||
This PR has been automatically closed because it has not had recent
|
||||
activity since being marked as stale.
|
||||
|
||||
Please reopen when work resumes.
|
9
ansible/roles/elastic.beats/.gitignore
vendored
Normal file
9
ansible/roles/elastic.beats/.gitignore
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
.kitchen/
|
||||
*.pyc
|
||||
.vendor
|
||||
.bundle
|
||||
Converging
|
||||
TODO
|
||||
.idea/
|
||||
beats.iml
|
||||
Dockerfile-*
|
136
ansible/roles/elastic.beats/.kitchen.yml
Normal file
136
ansible/roles/elastic.beats/.kitchen.yml
Normal file
|
@ -0,0 +1,136 @@
|
|||
---
|
||||
driver:
|
||||
name: docker
|
||||
|
||||
transport:
|
||||
max_ssh_sessions: 6
|
||||
|
||||
provisioner:
|
||||
name: ansible_playbook
|
||||
hosts: localhost
|
||||
roles_path: ./
|
||||
require_ansible_repo: true
|
||||
ansible_verbose: true
|
||||
idempotency_test: true
|
||||
|
||||
platforms:
|
||||
- name: ubuntu-16.04
|
||||
driver_config:
|
||||
image: ubuntu:16.04
|
||||
privileged: true
|
||||
provision_command:
|
||||
- apt-get update && apt-get install -y software-properties-common && add-apt-repository -y ppa:ansible/ansible
|
||||
- apt-get update && apt-get -y -q install ansible python-apt python-pycurl
|
||||
use_sudo: false
|
||||
- name: ubuntu-18.04
|
||||
driver_config:
|
||||
image: ubuntu:18.04
|
||||
privileged: true
|
||||
provision_command:
|
||||
- apt-get update && apt-get install -y software-properties-common && add-apt-repository -y ppa:ansible/ansible
|
||||
- apt-get update && apt-get -y -q install ansible python-apt python-pycurl
|
||||
- mkdir -p /run/sshd
|
||||
use_sudo: false
|
||||
- name: ubuntu-20.04
|
||||
driver_config:
|
||||
image: ubuntu:20.04
|
||||
privileged: true
|
||||
provision_command:
|
||||
- apt-get update && apt-get install -y software-properties-common && add-apt-repository -y ppa:ansible/ansible
|
||||
- apt-get update && apt-get -y -q install ansible python-apt python-pycurl
|
||||
use_sudo: false
|
||||
- name: debian-8
|
||||
driver_config:
|
||||
image: debian:8
|
||||
privileged: true
|
||||
provision_command:
|
||||
- echo "deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main" > /etc/apt/sources.list.d/ansible.list
|
||||
- apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367
|
||||
- apt-get update && apt-get -y install ansible
|
||||
use_sudo: false
|
||||
- name: debian-9
|
||||
driver_config:
|
||||
image: debian:9
|
||||
privileged: true
|
||||
provision_command:
|
||||
- apt-get update && apt-get -y install gnupg2
|
||||
- echo "deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main" > /etc/apt/sources.list.d/ansible.list
|
||||
- apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367
|
||||
- apt-get update && apt-get -y install ansible
|
||||
use_sudo: false
|
||||
- name: debian-10
|
||||
driver_config:
|
||||
image: debian:10
|
||||
privileged: true
|
||||
provision_command:
|
||||
- apt-get update && apt-get -y install gnupg2
|
||||
- echo "deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main" > /etc/apt/sources.list.d/ansible.list
|
||||
- apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367
|
||||
- apt-get update && apt-get -y install ansible
|
||||
use_sudo: false
|
||||
- name: centos-7
|
||||
driver_config:
|
||||
image: centos:7
|
||||
provision_command:
|
||||
- yum -y install epel-release
|
||||
- yum -y install ansible
|
||||
run_command: "/usr/sbin/init"
|
||||
privileged: true
|
||||
use_sudo: false
|
||||
- name: centos-8
|
||||
driver_config:
|
||||
image: centos:8
|
||||
provision_command:
|
||||
- yum -y install epel-release
|
||||
- yum -y install ansible
|
||||
run_command: "/usr/sbin/init"
|
||||
privileged: true
|
||||
use_sudo: false
|
||||
- name: amazonlinux-2
|
||||
driver_config:
|
||||
image: amazonlinux:2
|
||||
provision_command:
|
||||
- yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
|
||||
- yum -y install ansible
|
||||
volume:
|
||||
- <%=ENV['ES_XPACK_LICENSE_FILE']%>:/tmp/license.json
|
||||
- /etc # This fixes certain java file actions that check the mount point. Without this adding users fails for some docker storage drivers
|
||||
run_command: "/usr/sbin/init"
|
||||
privileged: true
|
||||
use_sudo: false
|
||||
suites:
|
||||
- name: standard
|
||||
provisioner:
|
||||
playbook: test/integration/standard.yml
|
||||
additional_copy_path:
|
||||
- "."
|
||||
run_list:
|
||||
attributes:
|
||||
- name: standard-6x
|
||||
provisioner:
|
||||
playbook: test/integration/standard-6x.yml
|
||||
additional_copy_path:
|
||||
- "."
|
||||
run_list:
|
||||
attributes:
|
||||
- name: multi
|
||||
provisioner:
|
||||
playbook: test/integration/multi.yml
|
||||
additional_copy_path:
|
||||
- "."
|
||||
run_list:
|
||||
attributes:
|
||||
- name: config
|
||||
provisioner:
|
||||
playbook: test/integration/config.yml
|
||||
additional_copy_path:
|
||||
- "."
|
||||
run_list:
|
||||
attributes:
|
||||
- name: oss
|
||||
provisioner:
|
||||
playbook: test/integration/oss.yml
|
||||
additional_copy_path:
|
||||
- "."
|
||||
run_list:
|
||||
attributes:
|
1
ansible/roles/elastic.beats/.ruby-version
Normal file
1
ansible/roles/elastic.beats/.ruby-version
Normal file
|
@ -0,0 +1 @@
|
|||
2.5.7
|
203
ansible/roles/elastic.beats/CHANGELOG.md
Normal file
203
ansible/roles/elastic.beats/CHANGELOG.md
Normal file
|
@ -0,0 +1,203 @@
|
|||
# Changelog
|
||||
|
||||
## 7.12.0
|
||||
|
||||
* 7.12.0 as default version.
|
||||
* 6.8.15 as 6.x tested version
|
||||
|
||||
|
||||
| PR | Author | Title |
|
||||
| --- | --- | --- |
|
||||
| [#138](https://github.com/elastic/ansible-beats/pull/138) | [@jmlrt](https://github.com/jmlrt) | [meta] fix changelog after 7.11.2 release |
|
||||
|
||||
|
||||
## 7.11.2
|
||||
|
||||
* 7.11.2 as default version.
|
||||
|
||||
| PR | Author | Title |
|
||||
| --- | --- | --- |
|
||||
| [#135](https://github.com/elastic/ansible-beats/pull/135) | [@v1v](https://github.com/v1v) | Update metadata reference for CentOS 8 |
|
||||
| [#134](https://github.com/elastic/ansible-beats/pull/134) | [@v1v](https://github.com/v1v) | Remove Ubuntu-14.04 support |
|
||||
| [#118](https://github.com/elastic/ansible-beats/pull/118) | [@v1v](https://github.com/v1v) | Support ubuntu-20 |
|
||||
| [#116](https://github.com/elastic/ansible-beats/pull/116) | [@v1v](https://github.com/v1v) | Support debian 10 |
|
||||
| [#131](https://github.com/elastic/ansible-beats/pull/131) | [@jmlrt](https://github.com/jmlrt) | Copy ILM policy file with root permission |
|
||||
|
||||
|
||||
## 7.11.1
|
||||
|
||||
* 7.11.1 as default version.
|
||||
* 6.8.14 as 6.x tested version
|
||||
|
||||
## 7.10.2
|
||||
|
||||
* 7.10.2 as default version.
|
||||
|
||||
|
||||
| PR | Author | Title |
|
||||
| --- | --- | --- |
|
||||
| [#123](https://github.com/elastic/ansible-beats/pull/123) | [@jmlrt](https://github.com/jmlrt) | Cleanup init_script variable |
|
||||
|
||||
|
||||
## 7.10.1
|
||||
|
||||
* 7.10.1 as default version.
|
||||
|
||||
|
||||
| PR | Author | Title |
|
||||
| --- | --- | --- |
|
||||
| [#115](https://github.com/elastic/ansible-beats/pull/115) | [@v1v](https://github.com/v1v) | Support CentOS-8 |
|
||||
| [#120](https://github.com/elastic/ansible-beats/pull/120) | [@jmlrt](https://github.com/jmlrt) | Remove CentOS 6 support |
|
||||
|
||||
|
||||
## 7.10.0
|
||||
|
||||
* 7.10.0 as default version.
|
||||
|
||||
|
||||
| PR | Author | Title |
|
||||
| --- | --- | --- |
|
||||
| [#113](https://github.com/elastic/ansible-beats/pull/113) | [@jmlrt](https://github.com/jmlrt) | [meta] clean deprecated bumper script |
|
||||
|
||||
|
||||
## 7.9.3
|
||||
|
||||
* 7.9.3 as default version.
|
||||
* 6.8.13 as 6.x tested version
|
||||
|
||||
## 7.9.2 - 2020/09/24
|
||||
|
||||
* 7.9.2 as default version
|
||||
|
||||
## 7.9.1 - 2020/09/03
|
||||
|
||||
* 7.9.1 as default version
|
||||
|
||||
## 7.9.0 - 2020/08/18
|
||||
|
||||
* 7.9.0 as default version
|
||||
* 6.8.12 as 6.x tested version
|
||||
|
||||
## 7.8.1 - 2020/07/28
|
||||
|
||||
* 7.8.1 as default version
|
||||
* 6.8.11 as 6.x tested version
|
||||
|
||||
| PR | Author | Title |
|
||||
|---------------------------------------------------------|------------------------------------|--------------------------|
|
||||
| [#89](https://github.com/elastic/ansible-beats/pull/89) | [@jmlrt](https://github.com/jmlrt) | Add amazonlinux2 support |
|
||||
|
||||
|
||||
## 7.8.0 - 2020/06/18
|
||||
|
||||
* 7.8.0 as default version
|
||||
|
||||
## 7.7.1 - 2020/06/04
|
||||
|
||||
* 7.7.1 as default version
|
||||
* 6.8.10 as 6.x tested version
|
||||
|
||||
## 7.7.0 - 2020/05/13
|
||||
|
||||
* 7.7.0 as default version
|
||||
* 6.8.9 as 6.x tested version
|
||||
* Fix CentOS tests in [#86](https://github.com/elastic/ansible-beats/pull/86) ([@jmlrt](https://github.com/jmlrt))
|
||||
|
||||
| PR | Author | Title |
|
||||
|---------------------------------------------------------|------------------------------------------|---------------------------------------------|
|
||||
| [#84](https://github.com/elastic/ansible-beats/pull/84) | [@kravietz](https://github.com/kravietz) | Minor formatting fixes to pass ansible-lint |
|
||||
|
||||
|
||||
## 7.6.2 - 2020/03/31
|
||||
|
||||
* 7.6.2 as default version
|
||||
* 6.8.8 as 6.x tested version
|
||||
|
||||
| PR | Author | Title |
|
||||
|---------------------------------------------------------|------------------------------------|---------------------------------------------------------------------------|
|
||||
| [#77](https://github.com/elastic/ansible-beats/pull/77) | [@jmlrt](https://github.com/jmlrt) | Add become to individual tasks |
|
||||
| [#75](https://github.com/elastic/ansible-beats/pull/75) | [@ktibi](https://github.com/ktibi) | Add option to disable the repo installation and lock package installation |
|
||||
| [#78](https://github.com/elastic/ansible-beats/pull/78) | [@astik](https://github.com/astik) | Aad task to create directory for default policies |
|
||||
|
||||
|
||||
## 7.6.1 - 2020/03/04
|
||||
|
||||
* 7.6.1 as default version
|
||||
|
||||
|
||||
## 7.6.0 - 2020/02/11
|
||||
|
||||
* 7.6.0 as default version
|
||||
|
||||
| PR | Author | Title |
|
||||
|---------------------------------------------------------|--------------------------------------------------------|------------------------------------|
|
||||
| [#69](https://github.com/elastic/ansible-beats/pull/69) | [@dependabot[bot]](https://github.com/apps/dependabot) | Bump rubyzip from 1.2.2 to 2.0.0 |
|
||||
| [#71](https://github.com/elastic/ansible-beats/pull/71) | [@jmlrt](https://github.com/jmlrt) | Fix filebeat example configuration |
|
||||
| [#72](https://github.com/elastic/ansible-beats/pull/72) | [@beand](https://github.com/beand) | Fixed typo |
|
||||
|
||||
|
||||
## 7.5.2 - 2020/01/21
|
||||
|
||||
* 7.5.2 as default version
|
||||
|
||||
| PR | Author | Title |
|
||||
|---------------------------------------------------------|------------------------------------|-----------------------------------------------|
|
||||
| [#66](https://github.com/elastic/ansible-beats/pull/66) | [@jmlrt](https://github.com/jmlrt) | [doc] switched relative URLs to absolute URLs |
|
||||
| [#67](https://github.com/elastic/ansible-beats/pull/67) | [@jmlrt](https://github.com/jmlrt) | [ci] bump ruby to 2.5.7 |
|
||||
|
||||
|
||||
## 7.5.1 - 2019/12/18
|
||||
|
||||
* 7.5.1 as default version
|
||||
* 6.8.6 as 6.x tested version
|
||||
|
||||
| PR | Author | Title |
|
||||
|---------------------------------------------------------|----------------------------------------------------|--------------------------|
|
||||
| [#61](https://github.com/elastic/ansible-beats/pull/61) | [@robsonpeixoto](https://github.com/robsonpeixoto) | Allow use oss repository |
|
||||
|
||||
|
||||
## 7.5.0 - 2019/12/02
|
||||
|
||||
* 7.5.0 as default version
|
||||
* 6.8.5 as 6.x tested version in [#57](https://github.com/elastic/ansible-beats/pull/57) [@jmlrt](https://github.com/jmlrt)
|
||||
|
||||
| PR | Author | Title |
|
||||
|---------------------------------------------------------|--------------------------------------------------|-----------------------------------------------------------------|
|
||||
| [#50](https://github.com/elastic/ansible-beats/pull/50) | [@jmlrt](https://github.com/jmlrt) | Add bumper script |
|
||||
| [#55](https://github.com/elastic/ansible-beats/pull/55) | [@tgadiev](https://github.com/tgadiev) | Update syntax to make it compliant to modern ansible-lint rules |
|
||||
| [#53](https://github.com/elastic/ansible-beats/pull/53) | [@jmlrt](https://github.com/jmlrt) | Indent yaml for config file |
|
||||
| [#51](https://github.com/elastic/ansible-beats/pull/51) | [@ktibi](https://github.com/ktibi) | Rename the handlers |
|
||||
| [#59](https://github.com/elastic/ansible-beats/pull/59) | [@MartinVerges](https://github.com/MartinVerges) | Beat config improvements |
|
||||
|
||||
|
||||
## 7.4.1 - 2019/10/23
|
||||
|
||||
* 7.4.1 as default version
|
||||
* 6.8.4 as 6.x tested version
|
||||
|
||||
| PR | Author | Title |
|
||||
|---------------------------------------------------------|------------------------------------|---------------------|
|
||||
| [#48](https://github.com/elastic/ansible-beats/pull/48) | [@jmlrt](https://github.com/jmlrt) | Fix probot newlines |
|
||||
|
||||
|
||||
## 7.4.0 - 2019/10/01
|
||||
|
||||
* 7.4.0 as default version
|
||||
|
||||
| PR | Author | Title |
|
||||
|---------------------------------------------------------|------------------------------------------|---------------------------------------------------------------------|
|
||||
| [#25](https://github.com/elastic/ansible-beats/pull/25) | [@jmlrt](https://github.com/jmlrt) | Update kitchen Gem dependencies |
|
||||
| [#6](https://github.com/elastic/ansible-beats/pull/6) | [@levonet](https://github.com/levonet) | Remove `beat_install` variable |
|
||||
| [#32](https://github.com/elastic/ansible-beats/pull/32) | [@astik](https://github.com/astik) | Remove unused `es_conf_dir` variable |
|
||||
| [#33](https://github.com/elastic/ansible-beats/pull/33) | [@astik](https://github.com/astik) | Replace custom filter with yaml handling |
|
||||
| [#10](https://github.com/elastic/ansible-beats/pull/10) | [@Meecr0b](https://github.com/Meecr0b) | Move the `repo_key` configuration to a variable |
|
||||
| [#34](https://github.com/elastic/ansible-beats/pull/34) | [@nyetwurk](https://github.com/nyetwurk) | Make sure the right beat service gets restarted |
|
||||
| [#38](https://github.com/elastic/ansible-beats/pull/38) | [@jmlrt](https://github.com/jmlrt) | Add probot config to manage stale issues/pr + GH issue template |
|
||||
| [#40](https://github.com/elastic/ansible-beats/pull/40) | [@nyetwurk](https://github.com/nyetwurk) | Make beats `repo_key` variable a unique name less likely to collide |
|
||||
| [#41](https://github.com/elastic/ansible-beats/pull/41) | [@jmlrt](https://github.com/jmlrt) | Enhance ansible-beats documentation |
|
||||
|
||||
|
||||
## 7.0.0 - 2019/05/09
|
||||
|
||||
* First release
|
||||
* 7.0.0 as default version
|
6
ansible/roles/elastic.beats/Gemfile
Normal file
6
ansible/roles/elastic.beats/Gemfile
Normal file
|
@ -0,0 +1,6 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem 'test-kitchen'
|
||||
gem 'kitchen-docker'
|
||||
gem 'kitchen-ansible'
|
||||
gem 'net-ssh'
|
117
ansible/roles/elastic.beats/Gemfile.lock
Normal file
117
ansible/roles/elastic.beats/Gemfile.lock
Normal file
|
@ -0,0 +1,117 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
bcrypt_pbkdf (1.0.1)
|
||||
builder (3.2.4)
|
||||
ed25519 (1.2.4)
|
||||
equatable (0.5.0)
|
||||
erubi (1.9.0)
|
||||
ffi (1.12.1)
|
||||
gssapi (1.3.0)
|
||||
ffi (>= 1.0.1)
|
||||
gyoku (1.3.1)
|
||||
builder (>= 2.1.2)
|
||||
httpclient (2.8.3)
|
||||
kitchen-ansible (0.50.0)
|
||||
net-ssh (>= 3)
|
||||
test-kitchen (>= 1.4)
|
||||
kitchen-docker (2.9.0)
|
||||
test-kitchen (>= 1.0.0)
|
||||
license-acceptance (1.0.11)
|
||||
pastel (~> 0.7)
|
||||
tomlrb (~> 1.2)
|
||||
tty-box (~> 0.3)
|
||||
tty-prompt (~> 0.18)
|
||||
little-plugger (1.1.4)
|
||||
logging (2.2.2)
|
||||
little-plugger (~> 1.1)
|
||||
multi_json (~> 1.10)
|
||||
mixlib-install (3.11.18)
|
||||
mixlib-shellout
|
||||
mixlib-versioning
|
||||
thor
|
||||
mixlib-shellout (2.4.4)
|
||||
mixlib-versioning (1.2.7)
|
||||
multi_json (1.14.1)
|
||||
necromancer (0.4.0)
|
||||
net-scp (2.0.0)
|
||||
net-ssh (>= 2.6.5, < 6.0.0)
|
||||
net-ssh (5.2.0)
|
||||
net-ssh-gateway (2.0.0)
|
||||
net-ssh (>= 4.0.0)
|
||||
nori (2.6.0)
|
||||
pastel (0.7.2)
|
||||
equatable (~> 0.5.0)
|
||||
tty-color (~> 0.4.0)
|
||||
rubyntlm (0.6.2)
|
||||
rubyzip (2.0.0)
|
||||
strings (0.1.5)
|
||||
strings-ansi (~> 0.1)
|
||||
unicode-display_width (~> 1.5)
|
||||
unicode_utils (~> 1.4)
|
||||
strings-ansi (0.1.0)
|
||||
test-kitchen (2.2.5)
|
||||
bcrypt_pbkdf (~> 1.0)
|
||||
ed25519 (~> 1.2)
|
||||
license-acceptance (~> 1.0, >= 1.0.11)
|
||||
mixlib-install (~> 3.6)
|
||||
mixlib-shellout (>= 1.2, < 3.0)
|
||||
net-scp (>= 1.1, < 3.0)
|
||||
net-ssh (>= 2.9, < 6.0)
|
||||
net-ssh-gateway (>= 1.2, < 3.0)
|
||||
thor (~> 0.19)
|
||||
winrm (~> 2.0)
|
||||
winrm-elevated (~> 1.0)
|
||||
winrm-fs (~> 1.1)
|
||||
thor (0.20.3)
|
||||
timers (4.3.0)
|
||||
tomlrb (1.2.8)
|
||||
tty-box (0.3.0)
|
||||
pastel (~> 0.7.2)
|
||||
strings (~> 0.1.4)
|
||||
tty-cursor (~> 0.6.0)
|
||||
tty-color (0.4.3)
|
||||
tty-cursor (0.6.1)
|
||||
tty-prompt (0.18.1)
|
||||
necromancer (~> 0.4.0)
|
||||
pastel (~> 0.7.0)
|
||||
timers (~> 4.0)
|
||||
tty-cursor (~> 0.6.0)
|
||||
tty-reader (~> 0.5.0)
|
||||
tty-reader (0.5.0)
|
||||
tty-cursor (~> 0.6.0)
|
||||
tty-screen (~> 0.6.4)
|
||||
wisper (~> 2.0.0)
|
||||
tty-screen (0.6.5)
|
||||
unicode-display_width (1.6.0)
|
||||
unicode_utils (1.4.0)
|
||||
winrm (2.3.4)
|
||||
builder (>= 2.1.2)
|
||||
erubi (~> 1.8)
|
||||
gssapi (~> 1.2)
|
||||
gyoku (~> 1.0)
|
||||
httpclient (~> 2.2, >= 2.2.0.2)
|
||||
logging (>= 1.6.1, < 3.0)
|
||||
nori (~> 2.0)
|
||||
rubyntlm (~> 0.6.0, >= 0.6.1)
|
||||
winrm-elevated (1.1.1)
|
||||
winrm (~> 2.0)
|
||||
winrm-fs (~> 1.0)
|
||||
winrm-fs (1.3.4)
|
||||
erubi (~> 1.8)
|
||||
logging (>= 1.6.1, < 3.0)
|
||||
rubyzip (~> 2.0)
|
||||
winrm (~> 2.0)
|
||||
wisper (2.0.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
kitchen-ansible
|
||||
kitchen-docker
|
||||
net-ssh
|
||||
test-kitchen
|
||||
|
||||
BUNDLED WITH
|
||||
1.17.0
|
13
ansible/roles/elastic.beats/LICENSE
Normal file
13
ansible/roles/elastic.beats/LICENSE
Normal file
|
@ -0,0 +1,13 @@
|
|||
Copyright (c) 2012-2016 Elasticsearch <http://www.elastic.co>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
31
ansible/roles/elastic.beats/Makefile
Normal file
31
ansible/roles/elastic.beats/Makefile
Normal file
|
@ -0,0 +1,31 @@
|
|||
default: build
|
||||
|
||||
SHELL:=/bin/bash -eux
|
||||
PATTERN := standard-ubuntu-1804
|
||||
|
||||
.PHONY: converge verify test login destroy list
|
||||
|
||||
setup:
|
||||
bundle install
|
||||
docker ps
|
||||
|
||||
converge:
|
||||
bundle exec kitchen converge $(PATTERN)
|
||||
|
||||
verify:
|
||||
bundle exec kitchen verify $(PATTERN)
|
||||
|
||||
test:
|
||||
bundle exec kitchen test $(PATTERN) --destroy=always
|
||||
|
||||
login:
|
||||
bundle exec kitchen login $(PATTERN)
|
||||
|
||||
destroy:
|
||||
bundle exec kitchen destroy $(PATTERN)
|
||||
|
||||
destroy-all:
|
||||
bundle exec kitchen destroy
|
||||
|
||||
list:
|
||||
bundle exec kitchen list
|
218
ansible/roles/elastic.beats/README.md
Normal file
218
ansible/roles/elastic.beats/README.md
Normal file
|
@ -0,0 +1,218 @@
|
|||
# ansible-beats
|
||||
[![Build Status](https://img.shields.io/jenkins/s/https/devops-ci.elastic.co/job/elastic+ansible-beats+master.svg)](https://devops-ci.elastic.co/job/elastic+ansible-beats+master/)
|
||||
[![Ansible Galaxy](https://img.shields.io/badge/ansible--galaxy-elastic.beats-blue.svg)](https://galaxy.ansible.com/elastic/beats/)
|
||||
|
||||
This role provides a generic means of installing Elastic supported Beats
|
||||
|
||||
**Tested Beats**
|
||||
|
||||
* Filebeat
|
||||
* MetricBeat (TopBeat in 1.x)
|
||||
* Packetbeat
|
||||
|
||||
**Tested Versions**
|
||||
|
||||
* 7.x
|
||||
* 6.x
|
||||
|
||||
**Tested Platforms**
|
||||
|
||||
* Ubuntu 16.04
|
||||
* Ubuntu 18.04
|
||||
* Ubuntu 20.04
|
||||
* Debian 8
|
||||
* Debian 9
|
||||
* Debian 10
|
||||
* CentOS 7
|
||||
* CentOS 8
|
||||
* Amazon Linux 2
|
||||
|
||||
## Usage
|
||||
|
||||
Create your Ansible playbook with your own tasks, and include the role beats. You will have to have this repository accessible within the context of playbook.
|
||||
|
||||
```sh
|
||||
ansible-galaxy install elastic.beats,v7.12.0
|
||||
```
|
||||
|
||||
Then create your playbook yaml adding the role beats.
|
||||
The application of the beats role results in the installation of a node on a host.
|
||||
|
||||
The simplest configuration therefore consists of:
|
||||
|
||||
```yaml
|
||||
hosts: localhost
|
||||
roles:
|
||||
- role: elastic.beats
|
||||
vars:
|
||||
beats_version: 7.12.0
|
||||
beat: filebeat
|
||||
beat_conf:
|
||||
filebeat:
|
||||
inputs:
|
||||
- type: log
|
||||
enabled: true
|
||||
paths:
|
||||
- /var/log/*.log
|
||||
```
|
||||
|
||||
The above installs Filebeat 7.12.0 on the hosts 'localhost'.
|
||||
|
||||
**Notes**:
|
||||
- Beats default version is described in [`beats_version`](https://github.com/elastic/ansible-beats/blob/master/defaults/main.yml#L4). You can override this variable in your playbook to install another version.
|
||||
While we are testing this role only with one 7.x and one 6.x version (respectively [7.12.0](https://github.com/elastic/ansible-beats/blob/master/defaults/main.yml#L4) and [6.8.15](https://github.com/elastic/ansible-beats/blob/master/test/integration/standard-6x.yml#L7) at the time of writing), this role should work with others version also in most cases.
|
||||
- Beat product is described in `beat` variable. While currently tested Beats are Filebeat, Metricbeat & Packetbeat, this role should work also with other member of [The Beats Family](https://www.elastic.co/products/beats) in most cases.
|
||||
|
||||
## Testing
|
||||
|
||||
This playbook uses [Kitchen](https://kitchen.ci/) for CI and local testing.
|
||||
|
||||
### Requirements
|
||||
|
||||
* Ruby
|
||||
* Bundler
|
||||
* Docker
|
||||
* Make
|
||||
|
||||
### Running the tests
|
||||
|
||||
To converge an Ubuntu 18.04 host
|
||||
```sh
|
||||
$ make converge
|
||||
```
|
||||
|
||||
To run the tests
|
||||
```sh
|
||||
$ make verify
|
||||
```
|
||||
|
||||
To list all of the different test suits
|
||||
```sh
|
||||
$ make list
|
||||
```
|
||||
|
||||
The default test suite is Ubuntu 18.04. If you want to test another suite you can override this with the `PATTERN` variable
|
||||
```sh
|
||||
$ make converge PATTERN=standard-centos-7
|
||||
```
|
||||
|
||||
The `PATTERN` is a kitchen pattern which can match multiple suites. To run all tests for CentOS
|
||||
```sh
|
||||
$ make converge PATTERN=centos-7
|
||||
```
|
||||
|
||||
When you are finished testing you can clean up everything with
|
||||
```sh
|
||||
$ make destroy-all
|
||||
```
|
||||
|
||||
### Basic Beats configuration
|
||||
|
||||
All Beats configuration parameters are supported. This is achieved using a configuration map parameter `beat_conf` which is serialized into the `${beat}.yml` file.
|
||||
The use of a map ensures the Ansible playbook does not need to be updated to reflect new/deprecated/plugin configuration parameters.
|
||||
|
||||
In addition to the `beat_conf` map, several other parameters are supported for additional functions e.g. script installation. These can be found in the role's `defaults/main.yml` file.
|
||||
|
||||
The following illustrates applying configuration parameters to Packetbeat instance.
|
||||
|
||||
```yaml
|
||||
- name: Example playbook for installing packetbeat
|
||||
hosts: localhost
|
||||
roles:
|
||||
- { role: beats, beat: "packetbeat",
|
||||
beat_conf: {
|
||||
"interfaces": {"device":"any"},
|
||||
"protocols": {
|
||||
"dns": {
|
||||
"ports": [53],
|
||||
"include_authorities":true
|
||||
},
|
||||
"http": {
|
||||
"ports": [80, 8080, 8000, 5000, 8002]
|
||||
},
|
||||
"memcache": {
|
||||
"ports": [11211]
|
||||
},
|
||||
"mysql": {
|
||||
"ports": [3306]
|
||||
},
|
||||
"pgsql": {
|
||||
"ports": [5432]
|
||||
},
|
||||
"redis": {
|
||||
"ports": [6379]
|
||||
},
|
||||
"thrift": {
|
||||
"ports": [9090]
|
||||
},
|
||||
"mongodb": {
|
||||
"ports": [27017]
|
||||
}
|
||||
}
|
||||
},
|
||||
output_conf : {
|
||||
"elasticsearch": {
|
||||
"hosts": ["localhost:9200"]
|
||||
}
|
||||
}
|
||||
}
|
||||
vars:
|
||||
use_repository: "true"
|
||||
```
|
||||
|
||||
### Additional Configuration
|
||||
|
||||
Supported variables are as follows:
|
||||
|
||||
- **beat** (*MANDATORY*): Beat product. Supported values are: "filebeat", "metricbeat" & "packetbeat" (others beats from [The Beats Family](https://www.elastic.co/products/beats) should work in most cases but aren't currently tested).
|
||||
- **beat_conf** (*MANDATORY*): Beat Configuration. Should be defined as a map.
|
||||
- **beats_version** (*Defaults to `7.12.0`*): Beats version.
|
||||
- **version_lock** (*Defaults to `false`*): Locks the installed version if set to true, thus preventing other processes from updating. This will not impact the roles ability to update the beat on subsequent runs (it unlocks and re-locks if required).
|
||||
- **use_repository** (*Defaults to `true`*): Use elastic repo for yum or apt if true. If false, a custom custom_package_url must be provided.
|
||||
- **beats_add_repository** (*Defaults to `{use_repository}`*): Install elastic repo for yum or apt if true. If false, the present repositories will be used. Useful if you already have beats packages in your repo.
|
||||
- **start_service** (*Defaults to `true`*): service will be started if true, false otherwise.
|
||||
- **restart_on_change** (*Defaults to `true`*): Changes to configuration or installed versions, will result in a restart if true.
|
||||
- **daemon_args** (*Applicable to version 1.x of beats*): Allows run time params to be passed to beats.
|
||||
- **logging_conf** (*Defaults to `{"files":{"rotateeverybytes":10485760}}`*): Logging configuration. Should be defined as a map. Map is serialized into logging section of beat config.
|
||||
- **shipper_conf** (*Applicable to version 1.x of beats*): Shipper configuration. Should be defined as a map . Map is serialized into shipper section of beat config.
|
||||
- **output_conf** (*Defaults to `{"elasticsearch":{"hosts":["localhost:9200"]}}`*): Output configuration. Map is serialized into output section of beat config.
|
||||
- **beats_pid_dir** (*Defaults to `/var/run`*): Location of beats pid file.
|
||||
- **beats_conf_dir** (*Defaults to `/etc/{beat}`*): Location of conf directory for beats configuration file.
|
||||
- **default_ilm_policy** (*Defaults undefined*): local path to default policy if any custom one is defined
|
||||
|
||||
### Focus on ILM
|
||||
|
||||
By default, *beat* will create a default policy defined as part of the beat being deployed.
|
||||
You can override default ILM setup by defining ILM conf as part of *beat_conf*.
|
||||
For example:
|
||||
|
||||
```
|
||||
- role: ansible-beats
|
||||
beat: metricbeat
|
||||
beat_conf:
|
||||
setup:
|
||||
ilm:
|
||||
policy_file: /etc/filebeat/policies/my-default-metricbeat.json
|
||||
overwrite: true
|
||||
metricbeat.modules:
|
||||
...
|
||||
default_ilm_policy: conf/my-default-metricbeat.json
|
||||
become: yes
|
||||
```
|
||||
|
||||
This will copy *conf/my-default-filebeat.json* to */etc/filebeat/policies/my-default-filebeat.json*.
|
||||
This policy will be used as default one for this beat.
|
||||
|
||||
## License
|
||||
|
||||
Apache 2.0
|
||||
|
||||
## Limitations
|
||||
|
||||
Multiple instances of the same beat cannot be installed on the same target server.
|
||||
|
||||
## Questions on Usage
|
||||
|
||||
We welcome questions on how to use the role. However, in order to keep the GitHub issues list focused on "issues" we ask the community to raise questions at https://discuss.elastic.co/c/beats. This is monitored by the maintainers.
|
||||
|
||||
Community Contributions always appreciated and welcome! Please ensure all contributions include tests as appropriate.
|
1
ansible/roles/elastic.beats/ansible.cfg
Normal file
1
ansible/roles/elastic.beats/ansible.cfg
Normal file
|
@ -0,0 +1 @@
|
|||
[defaults]
|
14
ansible/roles/elastic.beats/defaults/main.yml
Normal file
14
ansible/roles/elastic.beats/defaults/main.yml
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
# defaults file for beats
|
||||
beats_version: 7.12.0
|
||||
oss_version: false
|
||||
version_lock: false
|
||||
use_repository: true
|
||||
beats_add_repository: "{{ use_repository }}"
|
||||
start_service: true
|
||||
restart_on_change: true
|
||||
daemon_args: ""
|
||||
logging_conf: {"files":{"rotateeverybytes":10485760}}
|
||||
output_conf: {"elasticsearch":{"hosts":["localhost:9200"]}}
|
||||
beats_pid_dir: "/var/run"
|
||||
beats_conf_dir: "/etc/{{beat}}"
|
10
ansible/roles/elastic.beats/handlers/main.yml
Normal file
10
ansible/roles/elastic.beats/handlers/main.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
# handlers file for beats
|
||||
|
||||
- name: restart the service
|
||||
become: yes
|
||||
service:
|
||||
name: "{{ beat_product }}"
|
||||
state: restarted
|
||||
enabled: true
|
||||
when: start_service and restart_on_change and not beats_started.changed
|
2
ansible/roles/elastic.beats/meta/.galaxy_install_info
Normal file
2
ansible/roles/elastic.beats/meta/.galaxy_install_info
Normal file
|
@ -0,0 +1,2 @@
|
|||
install_date: Sat Apr 10 14:18:16 2021
|
||||
version: v7.12.0
|
28
ansible/roles/elastic.beats/meta/main.yml
Normal file
28
ansible/roles/elastic.beats/meta/main.yml
Normal file
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
allow_duplicates: true
|
||||
dependencies: []
|
||||
galaxy_info:
|
||||
role_name: beats
|
||||
author: Dale McDiarmid
|
||||
description: Beats for Linux
|
||||
company: "Elastic.co"
|
||||
issue_tracker_url: https://github.com/elastic/ansible-beats/issues
|
||||
license: "license (Apache)"
|
||||
min_ansible_version: 2.0
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
- 7
|
||||
- 8
|
||||
- name: Debian
|
||||
versions:
|
||||
- all
|
||||
- name: Ubuntu
|
||||
versions:
|
||||
- all
|
||||
galaxy_tags:
|
||||
- beats
|
||||
- elastic
|
||||
- elk
|
||||
- logging
|
||||
- monitoring
|
87
ansible/roles/elastic.beats/tasks/beats-config.yml
Normal file
87
ansible/roles/elastic.beats/tasks/beats-config.yml
Normal file
|
@ -0,0 +1,87 @@
|
|||
---
|
||||
# Configure Beats Node
|
||||
|
||||
- name: Set default facts
|
||||
set_fact:
|
||||
pid_file: '{{ beats_pid_dir }}/{{ beat }}.pid'
|
||||
instance_default_file: '{{ default_file }}/{{ beat }}'
|
||||
conf_file: '{{ beats_conf_dir }}/{{ beat }}.yml'
|
||||
beat_output_conf:
|
||||
output: '{{ output_conf }}'
|
||||
|
||||
- name: Set beat_shipper_conf
|
||||
set_fact:
|
||||
beat_shipper_conf:
|
||||
shipper: '{{ shipper_conf }}'
|
||||
when: shipper_conf is defined
|
||||
|
||||
- name: Set beat_logging_conf
|
||||
set_fact:
|
||||
beat_logging_conf:
|
||||
logging: '{{ logging_conf }}'
|
||||
|
||||
- name: Check pid_dir status
|
||||
stat:
|
||||
path: '{{ beats_pid_dir }}'
|
||||
register: pid_stat
|
||||
|
||||
- name: Create PID Directory
|
||||
become: yes
|
||||
file:
|
||||
path: '{{ beats_pid_dir }}'
|
||||
state: directory
|
||||
when: pid_stat.stat.isdir is not defined or pid_stat.stat.islnk is not defined
|
||||
|
||||
# fail if pid and config directories are not links or not directories i.e files
|
||||
|
||||
- name: Create Config Directory
|
||||
become: yes
|
||||
file:
|
||||
path: '{{ beats_conf_dir }}'
|
||||
state: directory
|
||||
|
||||
# Copy the default file
|
||||
- name: Copy Default File for Instance
|
||||
become: yes
|
||||
template:
|
||||
src: beat.j2
|
||||
dest: '{{ instance_default_file }}'
|
||||
mode: 0644
|
||||
force: true
|
||||
owner: root
|
||||
group: root
|
||||
notify: restart the service
|
||||
|
||||
# Copy templated config file
|
||||
- name: Copy Configuration File for {{ beat }}
|
||||
become: yes
|
||||
template:
|
||||
src: beat.yml.j2
|
||||
dest: '{{ conf_file }}'
|
||||
mode: 0644
|
||||
force: true
|
||||
owner: root
|
||||
group: root
|
||||
notify: restart the service
|
||||
|
||||
# Copy default ILM policy file
|
||||
- name: Create default policies config directory
|
||||
become: yes
|
||||
file:
|
||||
path: '{{ beat_conf.setup.ilm.policy_file | dirname }}'
|
||||
state: directory
|
||||
mode: 0755
|
||||
owner: root
|
||||
group: root
|
||||
when: default_ilm_policy is defined
|
||||
|
||||
- name: Copy default ILM policy file for {{ beat }}
|
||||
become: yes
|
||||
copy:
|
||||
src: '{{default_ilm_policy}}'
|
||||
dest: '{{ beat_conf.setup.ilm.policy_file }}'
|
||||
mode: 0644
|
||||
owner: root
|
||||
group: root
|
||||
when: default_ilm_policy is defined
|
||||
notify: restart the service
|
100
ansible/roles/elastic.beats/tasks/beats-debian.yml
Normal file
100
ansible/roles/elastic.beats/tasks/beats-debian.yml
Normal file
|
@ -0,0 +1,100 @@
|
|||
---
|
||||
|
||||
- name: Debian - Ensure apt-transport-https is installed
|
||||
become: yes
|
||||
apt:
|
||||
name: apt-transport-https
|
||||
state: present
|
||||
cache_valid_time: 86400
|
||||
when: use_repository | bool
|
||||
register: beat_install
|
||||
until: beat_install is succeeded
|
||||
notify: restart the service
|
||||
|
||||
- name: Debian - Ensure python-urllib3, python-openssl, python-pyasn1 & python-pip are installed
|
||||
become: yes
|
||||
apt:
|
||||
name:
|
||||
- python-urllib3
|
||||
- python-openssl
|
||||
- python-pyasn1
|
||||
- python-pip
|
||||
state: present
|
||||
register: libs_install
|
||||
until: libs_install is succeeded
|
||||
when:
|
||||
- use_repository | bool
|
||||
- ansible_distribution_release == "trusty"
|
||||
|
||||
- name: Debian - ensure ndg-httpsclient pip is installed
|
||||
become: yes
|
||||
pip:
|
||||
name: ndg-httpsclient
|
||||
state: present
|
||||
register: ndg_install
|
||||
until: ndg_install is succeeded
|
||||
when:
|
||||
- use_repository | bool
|
||||
- ansible_distribution_release == "trusty"
|
||||
|
||||
- name: Debian - Add Beats repository key
|
||||
become: yes
|
||||
apt_key:
|
||||
url: '{{ elastic_repo_key }}'
|
||||
state: present
|
||||
register: apt_key_install
|
||||
until: apt_key_install is succeeded
|
||||
when: beats_add_repository | bool
|
||||
|
||||
- name: Debian - add beats repository
|
||||
become: yes
|
||||
apt_repository:
|
||||
repo: 'deb {{ repo_url }} stable main'
|
||||
state: present
|
||||
register: repo_install
|
||||
until: repo_install is succeeded
|
||||
when: beats_add_repository | bool
|
||||
|
||||
- name: Debian - unhold {{ beat }} version for install
|
||||
become: yes
|
||||
command: apt-mark unhold {{ beat }}
|
||||
changed_when: false
|
||||
|
||||
- name: Debian - Ensure {{ beat }} is installed
|
||||
become: yes
|
||||
apt:
|
||||
name: >-
|
||||
{{ beat }}{% if beats_version is defined and beats_version|length>0 %}={{ beats_version }}{% endif %}
|
||||
state: present
|
||||
cache_valid_time: 86400
|
||||
register: beat_install
|
||||
until: beat_install is succeeded
|
||||
when: use_repository | bool
|
||||
notify: restart the service
|
||||
|
||||
- name: Debian - hold {{ beat }} version
|
||||
become: yes
|
||||
command: apt-mark hold {{ beat }}
|
||||
when: version_lock
|
||||
changed_when: false
|
||||
|
||||
- name: Set os_arch
|
||||
set_fact:
|
||||
os_arch: >-
|
||||
{{ ansible_architecture == 'x86_64' | ternary('amd64', 'i386') }}
|
||||
|
||||
- name: Debian - Download {{ beat }} from url
|
||||
get_url:
|
||||
url: >-
|
||||
{% if custom_package_url is defined %}{{ custom_package_url }}{%
|
||||
else %}{{ beats_package_url }}/{{ beat }}/{{ beat }}_{{ beats_version }}_{{ os_arch }}.deb{% endif %}
|
||||
dest: '/tmp/{{ beat }}_{{ beats_version }}_{{ os_arch }}.deb'
|
||||
validate_certs: false
|
||||
when: not use_repository | bool
|
||||
|
||||
- name: Debian - Ensure {{ beat }} is installed from downloaded package
|
||||
become: yes
|
||||
apt:
|
||||
deb: '/tmp/{{ beat }}_{{ beats_version }}_{{ os_arch }}.deb'
|
||||
when: not use_repository | bool
|
||||
notify: restart the service
|
19
ansible/roles/elastic.beats/tasks/beats-param-check.yml
Normal file
19
ansible/roles/elastic.beats/tasks/beats-param-check.yml
Normal file
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
- name: Check beat variable
|
||||
fail:
|
||||
msg: "beat must be specified and cannot be blank e.g. filebeat"
|
||||
when: beat is not defined or (beat | length == 0)
|
||||
|
||||
- name: Check beat_conf variable
|
||||
fail:
|
||||
msg: "beat_conf must be specified"
|
||||
when: beat_conf is not defined
|
||||
|
||||
- name: Check ILM variables
|
||||
fail:
|
||||
msg: "beat_conf.setup.ilm.policy_file must be specified if default_ilm_policy is used"
|
||||
when: default_ilm_policy is defined and beat_conf.setup.ilm.policy_file is not defined
|
||||
|
||||
- name: Set beats_major_version
|
||||
set_fact:
|
||||
beats_major_version: '{% if oss_version %}oss-{% endif %}{{ beats_version.split(".")[0] }}.x'
|
59
ansible/roles/elastic.beats/tasks/beats-redhat.yml
Normal file
59
ansible/roles/elastic.beats/tasks/beats-redhat.yml
Normal file
|
@ -0,0 +1,59 @@
|
|||
---
|
||||
- name: Redhat - add beats repository
|
||||
become: yes
|
||||
template:
|
||||
src: beats.repo.j2
|
||||
dest: /etc/yum.repos.d/beats.repo
|
||||
when: beats_add_repository | bool
|
||||
|
||||
- name: RedHat - install yum-version-lock
|
||||
become: yes
|
||||
yum:
|
||||
name: yum-plugin-versionlock
|
||||
state: present
|
||||
update_cache: true
|
||||
when: version_lock | bool
|
||||
register: versionlock_install
|
||||
until: versionlock_install is succeeded
|
||||
|
||||
- name: RedHat - unlock {{ beat }} for install
|
||||
become: yes
|
||||
shell: yum versionlock delete {{ beat }} || true
|
||||
changed_when: false
|
||||
when: version_lock | bool
|
||||
tags:
|
||||
- skip_ansible_lint
|
||||
|
||||
- name: RedHat - Ensure {{ beat }} is installed
|
||||
become: yes
|
||||
yum:
|
||||
name: >-
|
||||
{{ beat }}{% if beats_version is defined and beats_version|length %}-{{ beats_version }}{% endif %}
|
||||
state: present
|
||||
update_cache: true
|
||||
register: beat_install
|
||||
until: beat_install is succeeded
|
||||
when: use_repository | bool
|
||||
notify: restart the service
|
||||
|
||||
- name: RedHat - lock {{ beat }} version
|
||||
become: yes
|
||||
shell: >-
|
||||
yum versionlock add
|
||||
{{ beat }}{% if beats_version is defined and beats_version|length %}-{{ beats_version }}{% endif %}
|
||||
when: version_lock | bool
|
||||
changed_when: false
|
||||
tags:
|
||||
- skip_ansible_lint
|
||||
|
||||
- name: RedHat - Install {{ beat }} from url
|
||||
become: yes
|
||||
yum:
|
||||
name: >-
|
||||
{% if custom_package_url is defined %}{{ custom_package_url }}{%
|
||||
else %}{{ beats_package_url }}/{{ beat }}-{{ beats_version }}-{{ ansible_architecture }}.rpm{% endif %}
|
||||
state: present
|
||||
register: beat_install
|
||||
until: beat_install is succeeded
|
||||
when: not use_repository
|
||||
notify: restart the service
|
24
ansible/roles/elastic.beats/tasks/beats.yml
Normal file
24
ansible/roles/elastic.beats/tasks/beats.yml
Normal file
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
# Install OS specific beats
|
||||
|
||||
- name: Include specific Beats
|
||||
include_tasks: beats-debian.yml
|
||||
when: ansible_os_family == 'Debian'
|
||||
|
||||
- name: Include specific Beats
|
||||
include_tasks: beats-redhat.yml
|
||||
when: ansible_os_family == 'RedHat'
|
||||
|
||||
# Configuration file for beats
|
||||
- name: Beats configuration
|
||||
include_tasks: beats-config.yml
|
||||
|
||||
# Make sure the service is started, and restart if necessary
|
||||
- name: Start {{ beat_product }} service
|
||||
become: yes
|
||||
service:
|
||||
name: '{{ beat }}'
|
||||
state: started
|
||||
enabled: true
|
||||
when: start_service
|
||||
register: beats_started
|
17
ansible/roles/elastic.beats/tasks/main.yml
Normal file
17
ansible/roles/elastic.beats/tasks/main.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
# tasks file for beats
|
||||
|
||||
- name: check-parameters
|
||||
include_tasks: beats-param-check.yml
|
||||
|
||||
- name: define beat product
|
||||
set_fact:
|
||||
beat_product: "{{ beat }}"
|
||||
|
||||
- name: os-specific vars
|
||||
include_vars: '{{ ansible_os_family }}.yml'
|
||||
|
||||
- include_tasks: beats.yml
|
||||
|
||||
- name: Force all notified handlers to run at this point, not waiting for normal sync points
|
||||
meta: flush_handlers
|
7
ansible/roles/elastic.beats/templates/beat.j2
Normal file
7
ansible/roles/elastic.beats/templates/beat.j2
Normal file
|
@ -0,0 +1,7 @@
|
|||
################################
|
||||
# {{beat}}
|
||||
################################
|
||||
|
||||
# Beats PID File
|
||||
PIDFILE={{pid_file}}
|
||||
DAEMON_ARGS="-c {{conf_file}} {{daemon_args}}"
|
22
ansible/roles/elastic.beats/templates/beat.yml.j2
Normal file
22
ansible/roles/elastic.beats/templates/beat.yml.j2
Normal file
|
@ -0,0 +1,22 @@
|
|||
# {{ ansible_managed }}
|
||||
|
||||
################### {{beat}} Configuration #########################
|
||||
|
||||
############################# {{beat}} ######################################
|
||||
{{ beat_conf | to_nice_yaml(indent=2) }}
|
||||
|
||||
###############################################################################
|
||||
############################# Libbeat Config ##################################
|
||||
# Base config file used by all other beats for using libbeat features
|
||||
|
||||
############################# Output ##########################################
|
||||
|
||||
{{ beat_output_conf | to_nice_yaml(indent=2) }}
|
||||
|
||||
{% if shipper_conf is defined %}############################# Shipper #########################################
|
||||
|
||||
{{ beat_shipper_conf | to_nice_yaml(indent=2) }}
|
||||
{% endif %}
|
||||
############################# Logging #########################################
|
||||
|
||||
{{ beat_logging_conf | to_nice_yaml(indent=2) }}
|
6
ansible/roles/elastic.beats/templates/beats.repo.j2
Normal file
6
ansible/roles/elastic.beats/templates/beats.repo.j2
Normal file
|
@ -0,0 +1,6 @@
|
|||
[beats]
|
||||
name=Elastic Beats Repository
|
||||
baseurl={{ repo_url }}
|
||||
enabled=1
|
||||
gpgkey={{ elastic_repo_key }}
|
||||
gpgcheck=1
|
46
ansible/roles/elastic.beats/test/integration/config.yml
Normal file
46
ansible/roles/elastic.beats/test/integration/config.yml
Normal file
|
@ -0,0 +1,46 @@
|
|||
---
|
||||
# Install specific version here
|
||||
- name: wrapper playbook for kitchen testing beats
|
||||
hosts: localhost
|
||||
roles:
|
||||
- role: ansible-beats
|
||||
beat: packetbeat
|
||||
version_lock: true
|
||||
beat_conf:
|
||||
interfaces:
|
||||
device: any
|
||||
protocols:
|
||||
dns:
|
||||
ports:
|
||||
- 53
|
||||
include_authorities: true
|
||||
http:
|
||||
ports:
|
||||
- 80
|
||||
- 8080
|
||||
- 8000
|
||||
- 5000
|
||||
- 8002
|
||||
memcache:
|
||||
ports:
|
||||
- 11211
|
||||
mysql:
|
||||
ports:
|
||||
- 3306
|
||||
pgsql:
|
||||
ports:
|
||||
- 5432
|
||||
redis:
|
||||
ports:
|
||||
- 6379
|
||||
thrift:
|
||||
ports:
|
||||
- 9090
|
||||
mongodb:
|
||||
ports:
|
||||
- 27017
|
||||
output_conf:
|
||||
elasticsearch:
|
||||
hosts: ["localhost:9200"]
|
||||
vars:
|
||||
use_repository: true
|
|
@ -0,0 +1,49 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'Config Tests' do
|
||||
|
||||
describe service('packetbeat') do
|
||||
it { should be_running }
|
||||
end
|
||||
|
||||
describe package('packetbeat') do
|
||||
it { should be_installed }
|
||||
end
|
||||
|
||||
describe file('/etc/packetbeat/packetbeat.yml') do
|
||||
it { should be_file }
|
||||
it { should be_owned_by 'root' }
|
||||
end
|
||||
|
||||
describe file('/etc/packetbeat/packetbeat.yml') do
|
||||
it { should contain 'logging:' }
|
||||
it { should contain 'output:' }
|
||||
it { should contain 'protocols:' }
|
||||
it { should contain 'dns:' }
|
||||
it { should contain 'memcache:' }
|
||||
it { should contain 'http:' }
|
||||
it { should contain 'mongodb:' }
|
||||
it { should contain 'mysql:' }
|
||||
it { should contain 'pgsql:' }
|
||||
it { should contain 'redis:' }
|
||||
it { should contain 'thrift:' }
|
||||
it { should contain 'interfaces:' }
|
||||
it { should contain 'device: any' }
|
||||
end
|
||||
|
||||
describe file('/etc/init.d/packetbeat') do
|
||||
it { should exist }
|
||||
end
|
||||
|
||||
if os[:family] == 'redhat'
|
||||
describe command('yum versionlock list | grep packetbeat') do
|
||||
its(:stdout) { should match /packetbeat/ }
|
||||
end
|
||||
elsif ['debian', 'ubuntu'].include?(os[:family])
|
||||
describe command('sudo apt-mark showhold | grep packetbeat') do
|
||||
its(:stdout) { should match /packetbeat/ }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem 'rspec-retry'
|
|
@ -0,0 +1,11 @@
|
|||
require 'serverspec'
|
||||
set :backend, :exec
|
||||
|
||||
require 'rspec/retry'
|
||||
|
||||
RSpec.configure do |config|
|
||||
# show retry status in spec process
|
||||
config.verbose_retry = true
|
||||
# show exception that triggers a retry if verbose_retry is set to true
|
||||
config.display_try_failure_messages = true
|
||||
end
|
29
ansible/roles/elastic.beats/test/integration/multi.yml
Normal file
29
ansible/roles/elastic.beats/test/integration/multi.yml
Normal file
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
- name: wrapper playbook for kitchen testing "beats"
|
||||
hosts: localhost
|
||||
roles:
|
||||
- role: ansible-beats
|
||||
beat: filebeat
|
||||
beat_conf:
|
||||
filebeat:
|
||||
inputs:
|
||||
- paths:
|
||||
- /var/log/*.log
|
||||
type: log
|
||||
- role: ansible-beats
|
||||
beat: metricbeat
|
||||
beat_conf:
|
||||
metricbeat:
|
||||
modules:
|
||||
- module: "system"
|
||||
metricsets:
|
||||
- cpu
|
||||
- filesystem
|
||||
- network
|
||||
- process
|
||||
enabled: true
|
||||
period: 10s
|
||||
processes: [".*"]
|
||||
cpu_ticks: false
|
||||
vars:
|
||||
use_repository: true
|
|
@ -0,0 +1,57 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'Multi Tests' do
|
||||
|
||||
describe service('filebeat') do
|
||||
it { should be_running }
|
||||
end
|
||||
|
||||
describe package('filebeat') do
|
||||
it { should be_installed }
|
||||
end
|
||||
|
||||
describe file('/etc/filebeat/filebeat.yml') do
|
||||
it { should be_file }
|
||||
it { should be_owned_by 'root' }
|
||||
end
|
||||
|
||||
describe file('/etc/filebeat/filebeat.yml') do
|
||||
it { should contain 'filebeat:' }
|
||||
it { should contain 'logging:' }
|
||||
it { should contain 'output:' }
|
||||
end
|
||||
|
||||
describe file('/etc/init.d/filebeat') do
|
||||
it { should exist }
|
||||
end
|
||||
|
||||
describe service('metricbeat') do
|
||||
it { should be_running }
|
||||
end
|
||||
|
||||
describe package('metricbeat') do
|
||||
it { should be_installed }
|
||||
end
|
||||
|
||||
describe file('/etc/metricbeat/metricbeat.yml') do
|
||||
it { should be_file }
|
||||
it { should be_owned_by 'root' }
|
||||
end
|
||||
|
||||
describe file('/etc/metricbeat/metricbeat.yml') do
|
||||
it { should contain 'module: system' }
|
||||
it { should contain 'metricsets:' }
|
||||
it { should contain 'period: 10s' }
|
||||
it { should contain 'processes:' }
|
||||
it { should contain 'cpu_ticks:' }
|
||||
it { should contain 'logging:' }
|
||||
it { should contain 'output:' }
|
||||
end
|
||||
|
||||
describe file('/etc/init.d/metricbeat') do
|
||||
it { should exist }
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
15
ansible/roles/elastic.beats/test/integration/oss.yml
Normal file
15
ansible/roles/elastic.beats/test/integration/oss.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
- name: wrapper playbook for kitchen testing "beats"
|
||||
hosts: localhost
|
||||
roles:
|
||||
- role: ansible-beats
|
||||
beat: filebeat
|
||||
beat_conf:
|
||||
filebeat:
|
||||
inputs:
|
||||
- paths:
|
||||
- /var/log/*.log
|
||||
type: log
|
||||
vars:
|
||||
use_repository: true
|
||||
oss_version: true
|
|
@ -0,0 +1,39 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'Open Source Tests' do
|
||||
|
||||
describe service('filebeat') do
|
||||
it { should be_running }
|
||||
end
|
||||
|
||||
describe package('filebeat') do
|
||||
it { should be_installed }
|
||||
end
|
||||
|
||||
describe file('/etc/filebeat/filebeat.yml') do
|
||||
it { should be_file }
|
||||
it { should be_owned_by 'root' }
|
||||
end
|
||||
|
||||
describe file('/etc/filebeat/filebeat.yml') do
|
||||
it { should contain 'filebeat:' }
|
||||
it { should contain 'logging:' }
|
||||
it { should contain 'output:' }
|
||||
end
|
||||
|
||||
describe file('/etc/init.d/filebeat') do
|
||||
it { should exist }
|
||||
end
|
||||
|
||||
if os[:family] == 'redhat'
|
||||
describe command('yum versionlock list | grep filebeat') do
|
||||
its(:stdout) { should_not match /filebeat/ }
|
||||
end
|
||||
elsif ['debian', 'ubuntu'].include?(os[:family])
|
||||
describe command('sudo apt-mark showhold | grep filebeat') do
|
||||
its(:stdout) { should_not match /filebeat/ }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
16
ansible/roles/elastic.beats/test/integration/standard-6x.yml
Normal file
16
ansible/roles/elastic.beats/test/integration/standard-6x.yml
Normal file
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
- name: wrapper playbook for kitchen testing "beats"
|
||||
hosts: localhost
|
||||
roles:
|
||||
- role: ansible-beats
|
||||
beat: filebeat
|
||||
beat_conf:
|
||||
filebeat:
|
||||
prospectors:
|
||||
- paths:
|
||||
- /var/log/*.log
|
||||
input_type: log
|
||||
registry_file: /var/lib/filebeat/registry
|
||||
vars:
|
||||
beats_version: 6.8.15
|
||||
use_repository: "true"
|
|
@ -0,0 +1,39 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'Standard Tests' do
|
||||
|
||||
describe service('filebeat') do
|
||||
it { should be_running }
|
||||
end
|
||||
|
||||
describe package('filebeat') do
|
||||
it { should be_installed }
|
||||
end
|
||||
|
||||
describe file('/etc/filebeat/filebeat.yml') do
|
||||
it { should be_file }
|
||||
it { should be_owned_by 'root' }
|
||||
end
|
||||
|
||||
describe file('/etc/filebeat/filebeat.yml') do
|
||||
it { should contain 'filebeat:' }
|
||||
it { should contain 'logging:' }
|
||||
it { should contain 'output:' }
|
||||
end
|
||||
|
||||
describe file('/etc/init.d/filebeat') do
|
||||
it { should exist }
|
||||
end
|
||||
|
||||
if os[:family] == 'redhat'
|
||||
describe command('yum versionlock list | grep filebeat') do
|
||||
its(:stdout) { should_not match /filebeat/ }
|
||||
end
|
||||
elsif ['debian', 'ubuntu'].include?(os[:family])
|
||||
describe command('sudo apt-mark showhold | grep filebeat') do
|
||||
its(:stdout) { should_not match /filebeat/ }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
14
ansible/roles/elastic.beats/test/integration/standard.yml
Normal file
14
ansible/roles/elastic.beats/test/integration/standard.yml
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
- name: wrapper playbook for kitchen testing "beats"
|
||||
hosts: localhost
|
||||
roles:
|
||||
- role: ansible-beats
|
||||
beat: filebeat
|
||||
beat_conf:
|
||||
filebeat:
|
||||
inputs:
|
||||
- paths:
|
||||
- /var/log/*.log
|
||||
type: log
|
||||
vars:
|
||||
use_repository: true
|
|
@ -0,0 +1,39 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'Standard Tests' do
|
||||
|
||||
describe service('filebeat') do
|
||||
it { should be_running }
|
||||
end
|
||||
|
||||
describe package('filebeat') do
|
||||
it { should be_installed }
|
||||
end
|
||||
|
||||
describe file('/etc/filebeat/filebeat.yml') do
|
||||
it { should be_file }
|
||||
it { should be_owned_by 'root' }
|
||||
end
|
||||
|
||||
describe file('/etc/filebeat/filebeat.yml') do
|
||||
it { should contain 'filebeat:' }
|
||||
it { should contain 'logging:' }
|
||||
it { should contain 'output:' }
|
||||
end
|
||||
|
||||
describe file('/etc/init.d/filebeat') do
|
||||
it { should exist }
|
||||
end
|
||||
|
||||
if os[:family] == 'redhat'
|
||||
describe command('yum versionlock list | grep filebeat') do
|
||||
its(:stdout) { should_not match /filebeat/ }
|
||||
end
|
||||
elsif ['debian', 'ubuntu'].include?(os[:family])
|
||||
describe command('sudo apt-mark showhold | grep filebeat') do
|
||||
its(:stdout) { should_not match /filebeat/ }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
17
ansible/roles/elastic.beats/test/matrix.yml
Normal file
17
ansible/roles/elastic.beats/test/matrix.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
OS:
|
||||
- ubuntu-1604
|
||||
- ubuntu-1804
|
||||
- ubuntu-2004
|
||||
- debian-8
|
||||
- debian-9
|
||||
- debian-10
|
||||
- centos-7
|
||||
- centos-8
|
||||
- amazonlinux-2
|
||||
TEST_TYPE:
|
||||
- standard
|
||||
- standard-6x
|
||||
- multi
|
||||
- config
|
||||
- oss
|
3
ansible/roles/elastic.beats/vars/Debian.yml
Normal file
3
ansible/roles/elastic.beats/vars/Debian.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
default_file: "/etc/default"
|
||||
repo_url: "https://artifacts.elastic.co/packages/{{ beats_major_version }}/apt"
|
3
ansible/roles/elastic.beats/vars/RedHat.yml
Normal file
3
ansible/roles/elastic.beats/vars/RedHat.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
default_file: "/etc/sysconfig"
|
||||
repo_url: "https://artifacts.elastic.co/packages/{{ beats_major_version }}/yum"
|
5
ansible/roles/elastic.beats/vars/main.yml
Normal file
5
ansible/roles/elastic.beats/vars/main.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
# vars file for beats
|
||||
|
||||
beats_package_url: "https://download.elastic.co/beats"
|
||||
elastic_repo_key: "https://packages.elastic.co/GPG-KEY-elasticsearch"
|
173
ansible/roles/elnappo.check_mk_agent/.gitignore
vendored
Normal file
173
ansible/roles/elnappo.check_mk_agent/.gitignore
vendored
Normal file
|
@ -0,0 +1,173 @@
|
|||
# Created by https://www.gitignore.io
|
||||
|
||||
### OSX ###
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear on external disk
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
|
||||
### Windows ###
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
|
||||
### Linux ###
|
||||
*~
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
### Python ###
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# celery beat schedule file
|
||||
celerybeat-schedule
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
### Python Patch ###
|
||||
.venv/
|
20
ansible/roles/elnappo.check_mk_agent/.travis.yml
Normal file
20
ansible/roles/elnappo.check_mk_agent/.travis.yml
Normal file
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
language: python
|
||||
services: docker
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- MOLECULE_DISTRO: ubuntu1604
|
||||
- MOLECULE_DISTRO: ubuntu1804
|
||||
- MOLECULE_DISTRO: debian8
|
||||
- MOLECULE_DISTRO: debian9
|
||||
- MOLECULE_DISTRO: centos7
|
||||
|
||||
install:
|
||||
- pip install molecule docker
|
||||
|
||||
script:
|
||||
- molecule test
|
||||
|
||||
notifications:
|
||||
webhooks: https://galaxy.ansible.com/api/v1/notifications/
|
13
ansible/roles/elnappo.check_mk_agent/.yamllint
Normal file
13
ansible/roles/elnappo.check_mk_agent/.yamllint
Normal file
|
@ -0,0 +1,13 @@
|
|||
extends: default
|
||||
|
||||
rules:
|
||||
braces:
|
||||
max-spaces-inside: 1
|
||||
level: error
|
||||
brackets:
|
||||
max-spaces-inside: 1
|
||||
level: error
|
||||
line-length: disable
|
||||
# NOTE(retr0h): Templates no longer fail this lint rule.
|
||||
# Uncomment if running old Molecule templates.
|
||||
# truthy: disable
|
22
ansible/roles/elnappo.check_mk_agent/LICENSE
Normal file
22
ansible/roles/elnappo.check_mk_agent/LICENSE
Normal file
|
@ -0,0 +1,22 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 elnappo
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
79
ansible/roles/elnappo.check_mk_agent/README.md
Normal file
79
ansible/roles/elnappo.check_mk_agent/README.md
Normal file
|
@ -0,0 +1,79 @@
|
|||
# ansible-role-check-mk-agent
|
||||
[![Build Status](https://travis-ci.org/elnappo/ansible-role-check-mk-agent.svg?branch=master)](https://travis-ci.org/elnappo/ansible-role-check-mk-agent) [![Ansible Galaxy](https://img.shields.io/badge/galaxy-elnappo.check--mk--agent-blue.svg?style=flat)](https://galaxy.ansible.com/elnappo/check-mk-agent/)
|
||||
|
||||
Installs check mk\_agent. Run it with systemd-socket, SSH with sudo or SSH as root (default). Get more information about check\_mk at [https://mathias-kettner.de/check_mk.html]()
|
||||
|
||||
## Features
|
||||
* Install check_mk agent
|
||||
* Query check_mk agent over systemd-socket (only with check_mk_agent >= v1.4), SSH as root or SSH with sudo
|
||||
* Setup firewall if systemd-socket ist used (ufw or firewalld)
|
||||
* Add SSH host key to check_mk server
|
||||
* Install check_mk agent plugins/local checks and their dependencies
|
||||
* **Add hosts to check_mk server via WATO API**
|
||||
|
||||
## Requirements
|
||||
* Python requests >= v2.5.0
|
||||
|
||||
Tested on Ubuntu 16.04, 18.04 and CentOS 7, should also run under Debian and RedHat.
|
||||
|
||||
## Install
|
||||
$ ansible-galaxy install elnappo.check_mk_agent
|
||||
|
||||
## Role Variables
|
||||
* `check_mk_agent_over_ssh: True`
|
||||
* `check_mk_agent_with_sudo: False` Adds a user which is allowed to run check_mk_agent with sudo
|
||||
* `check_mk_agent_add_host_pubkey: False` Import SSH host keys into your check_mk servers known_hosts file
|
||||
* `check_mk_agent_monitoring_host:` Hostname of your check_mk server
|
||||
* `check_mk_agent_monitoring_user:` Username under which your check_mk instance runs
|
||||
* `check_mk_agent_plugins_requirements: []` Requirements for extra plugins
|
||||
* `check_mk_agent_plugins: []` List of extra plugins to install
|
||||
* `check_mk_agent_local_checks: {}`
|
||||
* `check_mk_agent_pubkey_file:` Path to SSH pubkey file
|
||||
* `check_mk_agent_add_to_wato: False`
|
||||
* `check_mk_agent_monitoring_host_folder: ""`
|
||||
* `check_mk_agent_monitoring_host_discovery_mode: new`
|
||||
* `check_mk_agent_monitoring_host_url:`
|
||||
* `check_mk_agent_monitoring_host_wato_username:`
|
||||
* `check_mk_agent_monitoring_host_wato_secret:`
|
||||
* `check_mk_agent_setup_firewall: True` Add firewall rule (ufw/firewalld) when using systemd-socket
|
||||
* `check_mk_agent_manual_install: False` Leave agent package installation to the user
|
||||
|
||||
## Included check_mk extra plugins
|
||||
Could be found under `files/plugins/`. As it is hard to keep these plugins
|
||||
up-to-date, these will be removed in a future version from the repository.
|
||||
|
||||
|
||||
## Dependencies
|
||||
None.
|
||||
|
||||
## Example Playbook
|
||||
|
||||
```yaml
|
||||
- hosts: servers
|
||||
vars:
|
||||
check_mk_agent_pubkey_file: omd_rsa.pub
|
||||
check_mk_agent_add_host_pubkey: True
|
||||
check_mk_agent_monitoring_host: checkmk.example.com
|
||||
check_mk_agent_monitoring_user: monitoring
|
||||
check_mk_agent_add_to_wato: True
|
||||
check_mk_agent_monitoring_host_url: http://cmk.example.com/monitoring/
|
||||
check_mk_agent_monitoring_host_wato_username: ansible
|
||||
check_mk_agent_monitoring_host_wato_secret: 7JTuBt6nETYHG1GS
|
||||
check_mk_agent_local_checks:
|
||||
filecount:
|
||||
src: files/check_mk_local_checks/filecount
|
||||
cache_time: 600
|
||||
filestat:
|
||||
src: files/check_mk_local_checks/filestat
|
||||
|
||||
roles:
|
||||
- elnappo.check_mk_agent
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
## Author Information
|
||||
|
||||
elnappo <elnappo@nerdpol.io>
|
14
ansible/roles/elnappo.check_mk_agent/defaults/main.yml
Normal file
14
ansible/roles/elnappo.check_mk_agent/defaults/main.yml
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
# defaults file for check_mk agent
|
||||
check_mk_agent_over_ssh: true
|
||||
check_mk_agent_with_sudo: false
|
||||
check_mk_agent_add_host_pubkey: false
|
||||
check_mk_agent_plugins_requirements: []
|
||||
check_mk_agent_plugins: []
|
||||
check_mk_agent_local_checks: {}
|
||||
check_mk_agent_pubkey_file:
|
||||
check_mk_agent_add_to_wato: false
|
||||
check_mk_agent_monitoring_host_folder: ""
|
||||
check_mk_agent_monitoring_host_discovery_mode: "new"
|
||||
check_mk_agent_setup_firewall: true
|
||||
check_mk_agent_manual_install: false
|
17
ansible/roles/elnappo.check_mk_agent/files/plugins/README
Normal file
17
ansible/roles/elnappo.check_mk_agent/files/plugins/README
Normal file
|
@ -0,0 +1,17 @@
|
|||
These plugins can be installed in the plugins directory of the Linux agent
|
||||
in /usr/lib/check_mk_agent/plugins/. Please only install the plugins that
|
||||
you really need.
|
||||
|
||||
If you want a plugin to be run asynchronously and also in
|
||||
a larger interval then the normal check interval, then you can
|
||||
copy it to a subdirectory named after a number of *minutes*,
|
||||
e.g.:
|
||||
|
||||
/usr/lib/check_mk_agent/plugins/60/mk_zypper
|
||||
|
||||
In that case the agent will:
|
||||
|
||||
- Run this plugin in the background and wait not for it to finish.
|
||||
- Store the result of the plugin in a cache file below /etc/check_mk/cache.
|
||||
- Use that file for one hour before running the script again.
|
||||
|
170
ansible/roles/elnappo.check_mk_agent/files/plugins/apache_status
Executable file
170
ansible/roles/elnappo.check_mk_agent/files/plugins/apache_status
Executable file
|
@ -0,0 +1,170 @@
|
|||
#!/usr/bin/python
|
||||
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# Check_MK-Agent-Plugin - Apache Server Status
|
||||
#
|
||||
# Fetches the server-status page from detected or configured apache
|
||||
# processes to gather status information about this apache process.
|
||||
#
|
||||
# To make this agent plugin work you have to load the status_module
|
||||
# into your apache process. It is also needed to enable the "server-status"
|
||||
# handler below the URL "/server-status".
|
||||
#
|
||||
# By default this plugin tries to detect all locally running apache processes
|
||||
# and to monitor them. If this is not good for your environment you might
|
||||
# create an apache_status.cfg file in MK_CONFDIR and populate the servers
|
||||
# list to prevent executing the detection mechanism.
|
||||
#
|
||||
# It is also possible to override or extend the ssl_ports variable to make the
|
||||
# check contact other ports than 443 with HTTPS requests.
|
||||
|
||||
import os, sys, urllib2, re, socket
|
||||
|
||||
config_dir = os.getenv("MK_CONFDIR", "/etc/check_mk")
|
||||
config_file = config_dir + "/apache_status.conf"
|
||||
|
||||
if not os.path.exists(config_file):
|
||||
config_file = config_dir + "/apache_status.cfg"
|
||||
|
||||
# We have to deal with socket timeouts. Python > 2.6
|
||||
# supports timeout parameter for the urllib2.urlopen method
|
||||
# but we are on a python 2.5 system here which seem to use the
|
||||
# default socket timeout. We are local here so set it to 1 second.
|
||||
socket.setdefaulttimeout(5.0)
|
||||
|
||||
# None or list of (proto, ipaddress, port) tuples.
|
||||
# proto is 'http' or 'https'
|
||||
servers = None
|
||||
ssl_ports = [ 443, ]
|
||||
|
||||
if os.path.exists(config_file):
|
||||
execfile(config_file)
|
||||
|
||||
|
||||
def try_detect_servers():
|
||||
results = []
|
||||
|
||||
for line in os.popen('netstat -tlnp 2>/dev/null').readlines():
|
||||
parts = line.split()
|
||||
# Skip lines with wrong format
|
||||
if len(parts) < 7 or '/' not in parts[6]:
|
||||
continue
|
||||
|
||||
pid, proc = parts[6].split('/', 1)
|
||||
to_replace = re.compile('^.*/')
|
||||
proc = to_replace.sub('', proc)
|
||||
|
||||
procs = [ 'apache2', 'httpd', 'httpd2-prefork', 'httpd2-worker', 'httpd.worker', 'fcgi-pm' ]
|
||||
# the pid/proc field length is limited to 19 chars. Thus in case of
|
||||
# long PIDs, the process names are stripped of by that length.
|
||||
# Workaround this problem here
|
||||
procs = [ p[:19 - len(pid) - 1] for p in procs ]
|
||||
|
||||
# Skip unwanted processes
|
||||
if proc not in procs:
|
||||
continue
|
||||
|
||||
address, port = parts[3].rsplit(':', 1)
|
||||
port = int(port)
|
||||
|
||||
# Use localhost when listening globally
|
||||
if address == '0.0.0.0':
|
||||
address = '127.0.0.1'
|
||||
elif address == '::':
|
||||
address = '[::1]'
|
||||
elif ':' in address:
|
||||
address = '[%s]' % address
|
||||
|
||||
# Switch protocol if port is SSL port. In case you use SSL on another
|
||||
# port you would have to change/extend the ssl_port list
|
||||
if port in ssl_ports:
|
||||
proto = 'https'
|
||||
else:
|
||||
proto = 'http'
|
||||
|
||||
results.append((proto, address, port))
|
||||
|
||||
return results
|
||||
|
||||
|
||||
if servers is None:
|
||||
servers = try_detect_servers()
|
||||
|
||||
|
||||
if not servers:
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
sys.stdout.write('<<<apache_status>>>\n')
|
||||
for server in servers:
|
||||
if isinstance(server, tuple):
|
||||
proto, address, port = server
|
||||
page = 'server-status'
|
||||
else:
|
||||
proto = server['protocol']
|
||||
address = server['address']
|
||||
port = server['port']
|
||||
page = server.get('page', 'server-status')
|
||||
|
||||
portspec = port and ":%d" % port or ""
|
||||
|
||||
try:
|
||||
url = '%s://%s%s/%s?auto' % (proto, address, portspec, page)
|
||||
# Try to fetch the status page for each server
|
||||
try:
|
||||
request = urllib2.Request(url, headers={"Accept" : "text/plain"})
|
||||
fd = urllib2.urlopen(request)
|
||||
except urllib2.URLError, e:
|
||||
if 'unknown protocol' in str(e):
|
||||
# HACK: workaround misconfigurations where port 443 is used for
|
||||
# serving non ssl secured http
|
||||
url = 'http://%s%s/server-status?auto' % (address, portspec)
|
||||
fd = urllib2.urlopen(url)
|
||||
else:
|
||||
raise
|
||||
except Exception, e:
|
||||
if 'doesn\'t match' in str(e):
|
||||
# HACK: workaround if SSL port is found and localhost is using
|
||||
# SSL connections but certificate does not match
|
||||
portspec = ':80'
|
||||
url = 'http://%s%s/server-status?auto' % (address, portspec)
|
||||
fd = urllib2.urlopen(url)
|
||||
else:
|
||||
raise
|
||||
|
||||
for line in fd.read().split('\n'):
|
||||
if not line.strip():
|
||||
continue
|
||||
if line.lstrip()[0] == '<':
|
||||
# Seems to be html output. Skip this server.
|
||||
break
|
||||
|
||||
sys.stdout.write("%s %s %s\n" % (address, port, line))
|
||||
except urllib2.HTTPError, e:
|
||||
sys.stderr.write('HTTP-Error (%s%s): %s %s\n' % (address, portspec, e.code, e))
|
||||
|
||||
except Exception, e:
|
||||
sys.stderr.write('Exception (%s%s): %s\n' % (address, portspec, e))
|
26
ansible/roles/elnappo.check_mk_agent/files/plugins/asmcmd.sh
Executable file
26
ansible/roles/elnappo.check_mk_agent/files/plugins/asmcmd.sh
Executable file
|
@ -0,0 +1,26 @@
|
|||
#!/bin/sh
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
su - griduser -c "asmcmd $@"
|
34
ansible/roles/elnappo.check_mk_agent/files/plugins/db2_mem
Executable file
34
ansible/roles/elnappo.check_mk_agent/files/plugins/db2_mem
Executable file
|
@ -0,0 +1,34 @@
|
|||
#!/bin/sh
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
INSTANCES=$(ps -ef | grep db2sysc | awk '{print $1}' | sort -u | grep -v root)
|
||||
|
||||
if [ "$INSTANCES" ] ; then
|
||||
echo "<<<db2_mem>>>"
|
||||
for INSTANCE in $INSTANCES; do
|
||||
echo "Instance $INSTANCE"
|
||||
su - $INSTANCE -c "db2pd -dbptnmem " | egrep '(Memory Limit|HWM usage)'
|
||||
done
|
||||
fi
|
48
ansible/roles/elnappo.check_mk_agent/files/plugins/dnsclient
Executable file
48
ansible/roles/elnappo.check_mk_agent/files/plugins/dnsclient
Executable file
|
@ -0,0 +1,48 @@
|
|||
#!/bin/sh
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# This check can be used to test the name resolution of a given host
|
||||
# address using the local resolver of the system this script is
|
||||
# running on.
|
||||
|
||||
HOSTADDRESSES=mathias-kettner.de
|
||||
|
||||
if [ -e $MK_CONFDIR/dnsclient.cfg ] ; then
|
||||
. $MK_CONFDIR/dnsclient.cfg
|
||||
fi
|
||||
|
||||
echo "<<<mrpe>>>"
|
||||
for HOSTADDRESS in $HOSTADDRESSES
|
||||
do
|
||||
ADDRESSES=`nslookup $HOSTADDRESS | sed -n -e 1,3d -e '/^Address: *\(.*\)$/s//\1/p'`
|
||||
if [ ! "$ADDRESSES" ] ; then
|
||||
STATE=2
|
||||
OUTPUT="CRIT - $HOSTADDRESS could not be resolved"
|
||||
else
|
||||
STATE=0
|
||||
OUTPUT="OK - $HOSTADDRESS resolved into $ADDRESSES"
|
||||
fi
|
||||
echo Resolve_$HOSTADDRESS $STATE $OUTPUT
|
||||
done
|
92
ansible/roles/elnappo.check_mk_agent/files/plugins/hpux_lunstats
Executable file
92
ansible/roles/elnappo.check_mk_agent/files/plugins/hpux_lunstats
Executable file
|
@ -0,0 +1,92 @@
|
|||
#!/usr/bin/ksh
|
||||
# Monitor status of LUNs on HP-UX
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# Put this file into /usr/lib/check_mk_agent/plugins. Then
|
||||
# reinventorize your host.
|
||||
# Actually querying these stats is quite slow since they freshly update
|
||||
# on each call. If you have a few 1000 luns then this will not work.
|
||||
|
||||
get_stats()
|
||||
{
|
||||
scsimgr get_stat -D $LUN | tr '\=' ':' | grep -e 'STATISTICS FOR LUN' -e 'Bytes' -e 'Total I/Os processed' -e 'I/O failure' -e 'IO failures due
|
||||
to'
|
||||
return $?
|
||||
}
|
||||
|
||||
|
||||
# Ex:
|
||||
#LUN PATH INFORMATION FOR LUN : /dev/pt/pt2
|
||||
#World Wide Identifier(WWID) =
|
||||
#LUN PATH INFORMATION FOR LUN : /dev/rdisk/disk5
|
||||
#World Wide Identifier(WWID) = 0x60a98000572d44745634645076556357
|
||||
#LUN PATH INFORMATION FOR LUN : /dev/rdisk/disk6
|
||||
|
||||
get_lun_map()
|
||||
{
|
||||
scsimgr lun_map | egrep '^[[:space:]]*(LUN PATH|World Wide Identifier)' | tr '\=' ':'
|
||||
}
|
||||
|
||||
|
||||
main()
|
||||
{
|
||||
get_lun_map | while read line ; do
|
||||
descr=$(echo $line | awk -F: '{print $1}')
|
||||
val=$( echo $line | awk -F: '{print $2}')
|
||||
case $descr in
|
||||
LUN*)
|
||||
if echo $val | grep /dev/rdisk 1>/dev/null; then
|
||||
DMP=yes
|
||||
LUN=$val
|
||||
else
|
||||
DMP=no
|
||||
unset LUN
|
||||
fi
|
||||
;;
|
||||
World*)
|
||||
if [ $DMP = "yes" ]; then
|
||||
echo "WWID: $val"
|
||||
get_stats $LUN
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Fehler:"
|
||||
echo $line
|
||||
echo $descr
|
||||
echo $val
|
||||
sleep 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Verify the system is using new multipath device model.
|
||||
if [ -d /dev/rdisk ] && [ -d /dev/disk ]; then
|
||||
echo '<<<hpux_lunstats:sep(58)>>>'
|
||||
main
|
||||
fi
|
||||
|
49
ansible/roles/elnappo.check_mk_agent/files/plugins/hpux_statgrab
Executable file
49
ansible/roles/elnappo.check_mk_agent/files/plugins/hpux_statgrab
Executable file
|
@ -0,0 +1,49 @@
|
|||
#!/bin/sh
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# this is for users who compiled statgrab on hp-ux.
|
||||
# note you'll need a 0.18+ version, from their github page at
|
||||
# https://github.com/i-scream/libstatgrab
|
||||
# flags used for compiling - disable documentation, examples and set*id
|
||||
|
||||
|
||||
if which statgrab > /dev/null ; then
|
||||
if statgrab const. cpu. general. mem. page. proc. swap. user. > /tmp/statgrab.$$ 2>/dev/null
|
||||
then
|
||||
for s in proc cpu page
|
||||
do
|
||||
echo "<<<statgrab_$s>>>"
|
||||
cat /tmp/statgrab.$$ | grep "^$s\." | cut -d. -f2-99 | sed 's/ *= */ /'
|
||||
done
|
||||
|
||||
echo '<<<statgrab_mem>>>'
|
||||
cat /tmp/statgrab.$$ | egrep "^(swap|mem)\." | sed 's/ *= */ /'
|
||||
|
||||
echo '<<<uptime>>>'
|
||||
cat /tmp/statgrab.$$ | egrep "^general\.uptime" | sed 's/.* //'
|
||||
|
||||
fi
|
||||
[ -f /tmp/statgrab.$$ ] && rm -f /tmp/statgrab.$$
|
||||
fi
|
85
ansible/roles/elnappo.check_mk_agent/files/plugins/isc_dhcpd
Executable file
85
ansible/roles/elnappo.check_mk_agent/files/plugins/isc_dhcpd
Executable file
|
@ -0,0 +1,85 @@
|
|||
#!/usr/bin/python
|
||||
# Monitor leases if ISC-DHCPD
|
||||
|
||||
import os, sys, time, re, calendar
|
||||
|
||||
conf_file = None
|
||||
for path in [ '/etc/dhcpd.conf', '/etc/dhcp/dhcpd.conf', '/usr/local/etc/dhcpd.conf' ]:
|
||||
if os.path.exists(path):
|
||||
conf_file = path
|
||||
break
|
||||
|
||||
leases_file = None
|
||||
for path in [
|
||||
'/var/lib/dhcp/db/dhcpd.leases',
|
||||
'/var/lib/dhcp/dhcpd.leases',
|
||||
'/var/lib/dhcpd/dhcpd.leases', # CentOS
|
||||
]:
|
||||
if os.path.exists(path):
|
||||
leases_file = path
|
||||
break
|
||||
|
||||
# If no configuration and leases are found, we assume that
|
||||
# no dhcpd is running.
|
||||
if not conf_file or not leases_file:
|
||||
sys.exit(0)
|
||||
|
||||
pidof_dhcpd = os.popen("pidof dhcpd").read().strip()
|
||||
sys.stdout.write('<<<isc_dhcpd>>>\n[general]\nPID: %s\n' % pidof_dhcpd)
|
||||
|
||||
sys.stdout.write('[pools]\n')
|
||||
|
||||
|
||||
def parse_config(filename):
|
||||
for line in file(filename):
|
||||
line = line.strip()
|
||||
if line.startswith("include"):
|
||||
included_file = re.search('include\s+"(.*)"', line).group(1)
|
||||
parse_config(included_file)
|
||||
elif line.startswith("range"):
|
||||
sys.stdout.write(line[5:].strip("\t ;") + "\n")
|
||||
|
||||
parse_config(conf_file)
|
||||
|
||||
|
||||
# lease 10.1.1.81 {
|
||||
# starts 3 2015/09/09 11:42:20;
|
||||
# ends 3 2015/09/09 19:42:20;
|
||||
# tstp 3 2015/09/09 19:42:20;
|
||||
# cltt 3 2015/09/09 11:42:20;
|
||||
# binding state free;
|
||||
# hardware ethernet a4:5e:60:de:1f:c3;
|
||||
# uid "\001\244^`\336\037\303";
|
||||
# set ddns-txt = "318c69bae8aeae6f8c723e96de933c7149";
|
||||
# set ddns-fwd-name = "Sebastians-MBP.dhcp.mathias-kettner.de";
|
||||
# }
|
||||
|
||||
sys.stdout.write('[leases]\n')
|
||||
now = time.time()
|
||||
ip_address = None
|
||||
binding_state = None
|
||||
seen_addresses = set()
|
||||
for line in file(leases_file):
|
||||
parts = line.strip().rstrip(";").split()
|
||||
if not parts:
|
||||
continue
|
||||
|
||||
if parts[0] == "lease":
|
||||
ip_address = parts[1]
|
||||
elif parts[0] == "ends":
|
||||
if parts[1] != "never":
|
||||
ends_date_string = parts[2] + " " + parts[3]
|
||||
ends_date = calendar.timegm(time.strptime(ends_date_string, "%Y/%m/%d %H:%M:%S"))
|
||||
if ends_date < now:
|
||||
ip_address = None # skip this address, this lease is outdated
|
||||
|
||||
elif parts[0] == "binding" and parts[1] == "state":
|
||||
binding_state = parts[2]
|
||||
|
||||
elif parts[0] == "}":
|
||||
if ip_address and binding_state == "active" and ip_address not in seen_addresses:
|
||||
sys.stdout.write("%s\n" % ip_address)
|
||||
seen_addresses.add(ip_address)
|
||||
ip_address = None
|
||||
binding_state = None
|
||||
|
52
ansible/roles/elnappo.check_mk_agent/files/plugins/jar_signature
Executable file
52
ansible/roles/elnappo.check_mk_agent/files/plugins/jar_signature
Executable file
|
@ -0,0 +1,52 @@
|
|||
#!/bin/bash
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# This agent uses the program "jarsigner" to read ssl certificate
|
||||
# information of jar files and outputs the information to stdout
|
||||
# for the Check_MK check.
|
||||
# We assume that all files in the jar archive are signed with the
|
||||
# same certificate. So we only deal with the last signed file here.
|
||||
|
||||
JAVA_HOME=/home/oracle/bin/jdk_latest_version
|
||||
JAR_PATH=/home/oracle/fmw/11gR2/as_1/forms/java/*.jar
|
||||
|
||||
# Let user override these defaults in a configuration file
|
||||
if [ -e $MK_CONFDIR/jar_signature.cfg ] ; then
|
||||
. $MK_CONFDIR/jar_signature.cfg
|
||||
fi
|
||||
|
||||
PATH=$JAVA_HOME/bin:$PATH
|
||||
|
||||
echo "<<<jar_signature>>>"
|
||||
for JAR in $JAR_PATH; do
|
||||
if [ -e "$JAR" ] ; then # avoid entry for '*.jar'
|
||||
echo "[[[${JAR##*/}]]]"
|
||||
OUTPUT=$(jarsigner -verify -verbose -certs "$JAR")
|
||||
LINE=$(echo "$OUTPUT" | grep -n ^s | tail -n1 | cut -d: -f1)
|
||||
echo "$(echo "$OUTPUT" | tail -n +$LINE)"
|
||||
echo
|
||||
fi
|
||||
done
|
||||
|
38
ansible/roles/elnappo.check_mk_agent/files/plugins/kaspersky_av
Executable file
38
ansible/roles/elnappo.check_mk_agent/files/plugins/kaspersky_av
Executable file
|
@ -0,0 +1,38 @@
|
|||
#!/bin/sh
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
if [ -f /opt/kaspersky/kav4fs/bin/kav4fs-control ]
|
||||
then
|
||||
echo "<<<kaspersky_av_updates:sep(58)>>>"
|
||||
/opt/kaspersky/kav4fs/bin/kav4fs-control --get-stat Update
|
||||
|
||||
echo "<<<kaspersky_av_quarantine:sep(58)>>>"
|
||||
/opt/kaspersky/kav4fs/bin/kav4fs-control -Q --get-stat
|
||||
|
||||
echo "<<<kaspersky_av_tasks>>>"
|
||||
/opt/kaspersky/kav4fs/bin/kav4fs-control --get-task-list
|
||||
|
||||
fi
|
||||
|
40
ansible/roles/elnappo.check_mk_agent/files/plugins/lnx_quota
Executable file
40
ansible/roles/elnappo.check_mk_agent/files/plugins/lnx_quota
Executable file
|
@ -0,0 +1,40 @@
|
|||
#!/bin/bash
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
if type repquota >/dev/null ; then
|
||||
echo "<<<lnx_quota>>>"
|
||||
|
||||
# User Quota
|
||||
for VOL in $(grep -E usr[j]?quota /etc/fstab | tr -s '\t' ' ' | cut -d' ' -f2); do
|
||||
echo "[[[usr:$VOL]]]"
|
||||
repquota -up $VOL | tail -n +6 | head -n -2
|
||||
done
|
||||
|
||||
# Group Quota
|
||||
for VOL in $(grep -E grp[j]?quota /etc/fstab | tr -s '\t' ' ' | cut -d' ' -f2); do
|
||||
echo "[[[grp:$VOL]]]"
|
||||
repquota -gp $VOL | tail -n +6 | head -n -2
|
||||
done
|
||||
fi
|
9
ansible/roles/elnappo.check_mk_agent/files/plugins/lvm
Executable file
9
ansible/roles/elnappo.check_mk_agent/files/plugins/lvm
Executable file
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
echo "<<<lvm_vgs>>>"
|
||||
vgs --units b --nosuffix --noheadings --separator ' '
|
||||
|
||||
echo "<<<lvm_lvs:sep(124)>>>"
|
||||
lvs --units b --nosuffix --noheadings --separator '|'
|
||||
|
||||
#echo "<<<lvm_pvs>>>"
|
||||
#pvs --units b --nosuffix --noheadings --separator ' '
|
55
ansible/roles/elnappo.check_mk_agent/files/plugins/mailman_lists
Executable file
55
ansible/roles/elnappo.check_mk_agent/files/plugins/mailman_lists
Executable file
|
@ -0,0 +1,55 @@
|
|||
#!/usr/bin/python
|
||||
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# This Check_MK-Agent plugin gathers information about mailinglists hosted
|
||||
# by the local mailman instance.
|
||||
|
||||
# Needed if you have located your mailman python modules not in default
|
||||
# python module paths
|
||||
import sys
|
||||
sys.path.append("/usr/local/mailman")
|
||||
sys.path.append("/usr/lib/mailman")
|
||||
|
||||
# Set to True to filter out all "hidden" mailinglists
|
||||
only_advertised = True
|
||||
|
||||
from Mailman import Utils, MailList # pylint: disable=import-error
|
||||
|
||||
# 1. list memberships
|
||||
sys.stdout.write('<<<mailman_lists>>>\n')
|
||||
total_members = set([])
|
||||
for name in sorted(Utils.list_names()):
|
||||
mlist = MailList.MailList(name, lock=0)
|
||||
if only_advertised and not mlist.advertised:
|
||||
continue
|
||||
|
||||
rmembers = mlist.getRegularMemberKeys()
|
||||
dmembers = mlist.getDigestMemberKeys()
|
||||
members = rmembers + dmembers
|
||||
total_members.update(members)
|
||||
|
||||
sys.stdout.write('%s %d\n' % (name, len(members)))
|
||||
sys.stdout.write('TOTAL %d\n' % len(total_members))
|
65
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_apt
Executable file
65
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_apt
Executable file
|
@ -0,0 +1,65 @@
|
|||
#!/bin/bash
|
||||
# Check for APT updates (Debian, Ubuntu)
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# TODO:
|
||||
# Einstellungen:
|
||||
# - upgrade oder dist-upgrade
|
||||
# - vorher ein update machen
|
||||
# Bakery:
|
||||
# - Bakelet anlegen
|
||||
# - Async-Zeit einstellbar machen und das Ding immer async laufen lassen
|
||||
# Check programmieren:
|
||||
# * Schwellwerte auf Anzahlen
|
||||
# * Regexen auf Pakete, die zu CRIT/WARN führen
|
||||
# - Graph malen mit zwei Kurven
|
||||
|
||||
# This variable can either be "upgrade" or "dist-upgrade"
|
||||
UPGRADE=upgrade
|
||||
DO_UPDATE=yes
|
||||
|
||||
|
||||
function check_apt_update {
|
||||
if [ "$DO_UPDATE" = yes ] ; then
|
||||
# NOTE: Even with -qq, apt-get update can output several lines to
|
||||
# stderr, e.g.:
|
||||
#
|
||||
# W: There is no public key available for the following key IDs:
|
||||
# 1397BC53640DB551
|
||||
apt-get update -qq 2> /dev/null
|
||||
fi
|
||||
apt-get -o 'Debug::NoLocking=true' -o 'APT::Get::Show-User-Simulation-Note=false' -s -qq "$UPGRADE" | grep -v '^Conf'
|
||||
}
|
||||
|
||||
|
||||
if type apt-get > /dev/null ; then
|
||||
echo '<<<apt:sep(0)>>>'
|
||||
out=$(check_apt_update)
|
||||
if [ -z "$out" ]; then
|
||||
echo "No updates pending for installation"
|
||||
else
|
||||
echo "$out"
|
||||
fi
|
||||
fi
|
44
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_ceph
Executable file
44
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_ceph
Executable file
|
@ -0,0 +1,44 @@
|
|||
#!/bin/bash
|
||||
# Check for APT updates (Debian, Ubuntu)
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2017 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
|
||||
# Config file must contain:
|
||||
# USER=client.admin
|
||||
# KEYRING=/etc/ceph/ceph.client.admin.keyring
|
||||
|
||||
|
||||
if [ -e "$MK_CONFDIR/ceph.cfg" ]; then
|
||||
. $MK_CONFDIR/ceph.cfg
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -z "$USER" ] && [ ! -z "$KEYRING" ]; then
|
||||
CEPH_CMD="ceph -n $USER --keyring=$KEYRING"
|
||||
echo "<<<ceph_status>>>"
|
||||
$CEPH_CMD -s -f json-pretty
|
||||
echo "<<<ceph_df>>>"
|
||||
$CEPH_CMD df detail
|
||||
fi
|
54
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_cups_queues
Executable file
54
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_cups_queues
Executable file
|
@ -0,0 +1,54 @@
|
|||
#!/bin/bash
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2017 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
if type lpstat > /dev/null 2>&1 ; then
|
||||
export LC_TIME="en_US.UTF-8"
|
||||
echo "<<<cups_queues>>>"
|
||||
CPRINTCONF=/etc/cups/printers.conf
|
||||
if [ -r "$CPRINTCONF" ] ; then
|
||||
LOCAL_PRINTERS=$(grep -E "<(Default)?Printer .*>" $CPRINTCONF | awk '{print $2}' | sed -e 's/>//')
|
||||
lpstat -p | while read LINE
|
||||
do
|
||||
PRINTER=$(echo "$LINE" | awk '{print $2}')
|
||||
if echo "$LOCAL_PRINTERS" | grep -q "$PRINTER"; then
|
||||
echo "$LINE"
|
||||
fi
|
||||
done
|
||||
echo '---'
|
||||
lpstat -o | while read LINE
|
||||
do
|
||||
PRINTER=${LINE%%-*}
|
||||
if echo "$LOCAL_PRINTERS" | grep -q "$PRINTER"; then
|
||||
echo "$LINE"
|
||||
fi
|
||||
done
|
||||
else
|
||||
PRINTER=$(lpstat -p)
|
||||
echo "$PRINTER"
|
||||
echo '---'
|
||||
QUEUE=$(lpstat -o | sort)
|
||||
echo "$QUEUE"
|
||||
fi
|
||||
fi
|
231
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_db2.aix
Executable file
231
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_db2.aix
Executable file
|
@ -0,0 +1,231 @@
|
|||
#!/usr/bin/ksh
|
||||
# Monitor DB/2 databases on AIX
|
||||
# $HOME/sqllib/db2profile
|
||||
|
||||
# This script can be called in two ways
|
||||
# Without any arguments:
|
||||
# Checks if cache of the instances is up to date and starts the
|
||||
# command 'mk_db.aix query {instance}' if applicable
|
||||
# If its outdated the script calls itself with the argument 'query'
|
||||
# With 'query {instance}' as argument:
|
||||
# Does the actual queries to the db2 instance and writes this info
|
||||
# into the cache file
|
||||
# Each instance has its own cache file and all of them are filled in parallel
|
||||
|
||||
if [ ! "$MK_CONFDIR" ] ; then
|
||||
echo "MK_CONFDIR not set!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! "$MK_VARDIR" ] ; then
|
||||
export MK_VARDIR=$MK_CONFDIR
|
||||
fi
|
||||
|
||||
function waitmax
|
||||
{
|
||||
TIMEOUT=${1}0
|
||||
SIGNAL=9
|
||||
shift
|
||||
|
||||
# Run command in background
|
||||
if [ "${#}" -ge 1 ] ; then
|
||||
ksh -c "$*" &
|
||||
else
|
||||
TEST=$(cat)
|
||||
ksh -c "$TEST" &
|
||||
fi
|
||||
|
||||
PID=$!
|
||||
|
||||
# Wait for termination within TIMOUT seconds
|
||||
while [ $TIMEOUT -gt 0 ]
|
||||
do
|
||||
TIMEOUT=$((TIMEOUT - 1))
|
||||
if [ ! -e /proc/$PID ] ; then
|
||||
return 0
|
||||
fi
|
||||
perl -e "select(undef, undef, undef, 0.1);"
|
||||
done
|
||||
|
||||
# Process did not terminate in time. Kill and
|
||||
# return with an error
|
||||
kill -9 $PID
|
||||
return 255
|
||||
}
|
||||
|
||||
function query_instance {
|
||||
INSTANCE=$1
|
||||
# find home directory
|
||||
HOMEDIR=$(grep "^$INSTANCE" /etc/passwd | awk -F: '{print $6}' | grep "$INSTANCE$")
|
||||
NOW=$(perl -e "print time();")
|
||||
|
||||
waitmax 200 << WAITMAX
|
||||
su $INSTANCE << EOF
|
||||
|
||||
if [ ! -f $HOMEDIR/sqllib/db2profile ] ;
|
||||
then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
. $HOMEDIR/sqllib/db2profile >/dev/null 2>&1 ;
|
||||
|
||||
|
||||
function compare_version_greater_equal {
|
||||
GREATER_ONE=\\\$(echo "\\\$1 \\\$2" | awk "{if (\\\$1 >= \\\$2) print \\\$1; else print \\\$2}")
|
||||
if [ \\\$GREATER_ONE == \\\$1 ] ; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
echo '<<<db2_version:sep(1)>>>'
|
||||
DBVERSION=\\\$(db2 get snapshot for dbm | grep -e 'Product name' -e 'Service level' | awk -v FS='=' '{print \\\$2}' | sed 'N;s/\n/,/g' | sed 's/ //g')
|
||||
echo $INSTANCE \\\$DBVERSION
|
||||
VERSION_NUMBER=\\\$(echo \\\$DBVERSION | sed -e 's/DB2v\\\(.*\),.*/\\\1/' | awk -v FS="." '{print \\\$1"."\\\$2}')
|
||||
|
||||
DBS=\\\$(db2 list database directory on $HOMEDIR | grep 'Database name' | awk '{ print \\\$NF }')
|
||||
|
||||
GET_PORT=1
|
||||
DB_PORT='port 0'
|
||||
for DB in \\\$DBS; do
|
||||
db2 connect to \\\$DB > /dev/null;
|
||||
if [ $? -nq 0 ] ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ 1 -eq \\\$GET_PORT ] ; then
|
||||
# Each database in an instance has the same port information
|
||||
db2_tcp_service=\\\$(db2 -x get dbm cfg | grep $INSTANCE | grep "TCP/IP Service" | awk -v FS='=' '{print \\\$2}'|tr -d ' ')
|
||||
if ( grep \\\$db2_tcp_service /etc/services | grep -q "^\\\$db2_tcp_service " ); then
|
||||
DB_PORT='port '\\\$(grep \\\$db2_tcp_service /etc/services | grep "^\\\$db2_tcp_service " | awk '{print \\\$2}' | awk -v FS="/" '{print \\\$1}')
|
||||
fi
|
||||
GET_PORT=0
|
||||
fi
|
||||
|
||||
echo "<<<db2_tablespaces>>>"
|
||||
echo "[[[$INSTANCE:\\\$DB]]]"
|
||||
db2 "SELECT tbsp_name, tbsp_type, tbsp_state, tbsp_usable_size_kb, tbsp_total_size_kb, tbsp_used_size_kb, tbsp_free_size_kb FROM sysibmadm.tbsp_utilization WHERE tbsp_type = 'DMS' UNION ALL SELECT tu.tbsp_name, tu.tbsp_type, tu.tbsp_state, tu.tbsp_usable_size_kb, tu.tbsp_total_size_kb, tu.tbsp_used_size_kb, (cu.fs_total_size_kb - cu.fs_used_size_kb) AS tbsp_free_size_kb FROM sysibmadm.tbsp_utilization tu INNER JOIN ( SELECT tbsp_id, 1 AS fs_total_size_kb, 0 AS fs_used_size_kb FROM sysibmadm.container_utilization WHERE (fs_total_size_kb IS NULL OR fs_used_size_kb IS NULL) GROUP BY tbsp_id) cu ON (tu.tbsp_type = 'SMS' AND tu.tbsp_id = cu.tbsp_id) UNION ALL SELECT tu.tbsp_name, tu.tbsp_type, tu.tbsp_state, tu.tbsp_usable_size_kb, tu.tbsp_total_size_kb, tu.tbsp_used_size_kb, (cu.fs_total_size_kb - cu.fs_used_size_kb) AS tbsp_free_size_kb FROM sysibmadm.tbsp_utilization tu INNER JOIN ( SELECT tbsp_id, SUM(fs_total_size_kb) AS fs_total_size_kb, SUM(fs_used_size_kb) AS fs_used_size_kb FROM sysibmadm.container_utilization WHERE (fs_total_size_kb IS NOT NULL AND fs_used_size_kb IS NOT NULL) GROUP BY tbsp_id) cu ON (tu.tbsp_type = 'SMS' AND tu.tbsp_id = cu.tbsp_id)" | awk '{print \\\$1" "\\\$2" "\\\$3" "\\\$4" "\\\$5" "\\\$6" "\\\$7}' | sed -e '/^[ ]*$/d' -e '/^-/d' -e '/selected/d'
|
||||
|
||||
echo "<<<db2_counters>>>"
|
||||
echo "TIMESTAMP $NOW"
|
||||
cat \\\$(db2 get dbm cfg|grep "Default database path"|awk -v FS="=" '{print \\\$2"/sqllib/db2nodes.cfg"}'|tr -d ' ') | sed "s/\(.*\)/$INSTANCE:\\\$DB node \1/"
|
||||
db2 -x "SELECT deadlocks from sysibmadm.snapdb" | tr -d ' ' | sed "s/\(.*\)/$INSTANCE:\\\$DB deadlocks \1/"
|
||||
db2 -x "SELECT lock_waits from sysibmadm.snapdb" | tr -d ' ' | sed "s/\(.*\)/$INSTANCE:\\\$DB lockwaits \1/"
|
||||
db2 -x "SELECT sort_overflows from sysibmadm.snapdb" | tr -d ' ' | sed "s/\(.*\)/$INSTANCE:\\\$DB sortoverflows \1/"
|
||||
|
||||
echo "<<<db2_logsizes>>>"
|
||||
echo "[[[$INSTANCE:\\\$DB]]]"
|
||||
echo "TIMESTAMP $NOW"
|
||||
cat \\\$(db2 get dbm cfg|grep "Default database path"|awk -v FS="=" '{print \\\$2"/sqllib/db2nodes.cfg"}'|tr -d ' ') | sed 's/\(.*\)/node \1/'
|
||||
db2 -x "SELECT 'usedspace', total_log_used from sysibmadm.snapdb" | awk '{print \\\$1" "\\\$2}'
|
||||
db2 -x "SELECT NAME, VALUE FROM SYSIBMADM.DBCFG WHERE NAME IN ('logfilsiz','logprimary','logsecond')"| awk '{print \\\$1" "\\\$2}'
|
||||
|
||||
echo "<<<db2_connections>>>"
|
||||
echo "[[[$INSTANCE:\\\$DB]]]"
|
||||
echo \\\$DB_PORT
|
||||
echo "connections " | tr -d '\n'
|
||||
db2 list applications | grep -v Auth | grep -v Name | sed -e '/^$/d' | wc -l | tr -d ' '
|
||||
# TODO: the time command seems to be broken and outputs 1 second steps
|
||||
ksh -c "time db2 connect to \\\$DB > /dev/null" 2>&1 | grep real | awk '{print "latency "\\\$2}'| sed -e 's/m/:/' -e 's/s//'
|
||||
|
||||
echo "<<<db2_bp_hitratios>>>"
|
||||
echo "[[[$INSTANCE:\\\$DB]]]"
|
||||
cat \\\$(db2 get dbm cfg|grep "Default database path"|awk -v FS="=" '{print \\\$2"/sqllib/db2nodes.cfg"}'|tr -d ' ') | sed "s/\(.*\)/node \1/"
|
||||
db2 "SELECT SUBSTR(BP_NAME,1,14) AS BP_NAME, TOTAL_HIT_RATIO_PERCENT, DATA_HIT_RATIO_PERCENT, INDEX_HIT_RATIO_PERCENT, XDA_HIT_RATIO_PERCENT FROM SYSIBMADM.BP_HITRATIO" | grep -v "selected." | sed -e '/^$/d' -e '/^-/d'
|
||||
|
||||
echo "<<<db2_sort_overflow>>>"
|
||||
echo "[[[$INSTANCE:\\\$DB]]]"
|
||||
db2 -x "get snapshot for database on \\\$DB" | grep -e "^Total sorts" -e "^Sort overflows" | tr -d '='
|
||||
|
||||
echo "<<<db2_backup>>>"
|
||||
echo "[[[$INSTANCE:\\\$DB]]]"
|
||||
if compare_version_greater_equal \\\$VERSION_NUMBER 10.5; then
|
||||
# MON_GET_DATBASE(-2) gets information of all active members
|
||||
db2 -x "select LAST_BACKUP from TABLE (MON_GET_DATABASE(-2))" | grep -v "selected." | tail -n 1
|
||||
else
|
||||
db2 -x "select SQLM_ELM_LAST_BACKUP from table(SNAPSHOT_DATABASE( cast( null as VARCHAR(255)), cast(null as int))) as ref" | grep -v "selected." | tail -n 1
|
||||
fi
|
||||
|
||||
# disconnect from database
|
||||
db2 connect reset > /dev/null
|
||||
done
|
||||
EOF
|
||||
WAITMAX
|
||||
return $?
|
||||
}
|
||||
|
||||
if [ "$1" = "query" ]; then
|
||||
query_instance $2
|
||||
exit $?
|
||||
else
|
||||
#### RUN CACHED #####
|
||||
function file_age {
|
||||
/usr/bin/perl -e 'if (! -f $ARGV[0]){die "0000000"};$mtime=(stat($ARGV[0]))[9];print ($^T-$mtime);' "$1"
|
||||
}
|
||||
|
||||
if [ ! -d $MK_VARDIR/cache ]; then mkdir -p $MK_VARDIR/cache ; fi
|
||||
|
||||
|
||||
if [ -e "$MK_VARDIR/cache/mk_db2.aix.cache" ] ; then
|
||||
rm $MK_VARDIR/cache/mk_db2.aix.cache
|
||||
fi
|
||||
INSTANCES=$(ps -ef | grep [d]b2sysc | awk '{print $1 }')
|
||||
|
||||
# Output any section headers
|
||||
# If no data is available there will be at least the section headers
|
||||
# This happens when a database is down. In this scenario the db2_version check
|
||||
# should go CRIT and the other checks go stale
|
||||
echo "<<<db2_version:sep(1)>>>"
|
||||
echo "<<<db2_tablespaces>>>"
|
||||
echo "<<<db2_counters>>>"
|
||||
echo "<<<db2_logsizes>>>"
|
||||
echo "<<<db2_connections>>>"
|
||||
echo "<<<db2_bp_hitratios>>>"
|
||||
echo "<<<db2_sort_overflow>>>"
|
||||
echo "<<<db2_backup>>>"
|
||||
|
||||
for INSTANCE in $INSTANCES; do
|
||||
CACHEFILE="$MK_VARDIR/cache/mk_db2.aix.cache.$INSTANCE"
|
||||
MAXAGE=300
|
||||
|
||||
# Check if the creation of the cache takes way to long and delete this file
|
||||
# The process might have crashed...
|
||||
# Since the processes are called with waitmax it is very unlikely that
|
||||
# there are still unwanted processes soiling the system.
|
||||
if [ -e "$CACHEFILE.new" ] ; then
|
||||
AGE=$(file_age "$CACHEFILE.new")
|
||||
if [ $AGE -ge $((MAXAGE * 10)) ] ; then
|
||||
rm "$CACHEFILE.new"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if the creation of the cache takes suspiciously long and return
|
||||
# nothing if the age (access time) of $CACHEFILE.new is twice the MAXAGE
|
||||
if [ -e "$CACHEFILE.new" ] ; then
|
||||
AGE=$(file_age "$CACHEFILE.new")
|
||||
if [ $AGE -ge $((MAXAGE * 2)) ] ; then
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if cache file exists and is recent enough
|
||||
USE_CACHEFILE=""
|
||||
if [ -s "$CACHEFILE" ] ; then
|
||||
AGE=$(file_age "$CACHEFILE")
|
||||
if [ $AGE -le $MAXAGE ] ; then USE_CACHEFILE=1 ; fi
|
||||
# Output the file in any case, even if it is
|
||||
# outdated. The new file will not yet be available
|
||||
cat "$CACHEFILE"
|
||||
fi
|
||||
|
||||
# Cache file outdated and new job not yet running? Start it
|
||||
if [ -z "$USE_CACHEFILE" -a ! -e "$CACHEFILE.new" ] ; then
|
||||
echo "set -o noclobber ; exec > \"$CACHEFILE.new\" || exit 1 ; ./$0 query $INSTANCE && mv \"$CACHEFILE.new\" \"$CACHEFILE\" || rm -f \"$CACHEFILE\" \"$CACHEFILE.new\"" | nohup ksh 2>/dev/null &
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
exit 0
|
147
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_db2.linux
Executable file
147
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_db2.linux
Executable file
|
@ -0,0 +1,147 @@
|
|||
#!/bin/bash
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2018 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# Agent plugin to monitor DB/2 databases on Linux.
|
||||
#
|
||||
# Note: The script has to be accessible and executable by the DB/2
|
||||
# instance users to function properly.
|
||||
#
|
||||
# The script is called in two different modes. Without arguments it:
|
||||
#
|
||||
# - outputs the db2_version section,
|
||||
# - collects all db2 instances and databases, and
|
||||
# - runs the script for each database as an instance user
|
||||
#
|
||||
# With arguments the script queries the information for each database and
|
||||
# outputs the corresponding sections.
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
if type timeout >/dev/null 2>&1 ; then
|
||||
function waitmax () {
|
||||
timeout "$@"
|
||||
}
|
||||
fi
|
||||
|
||||
INSTANCES=$(ps -ef | grep "[d]b2sysc" | awk '{print $1 }')
|
||||
|
||||
for INSTANCE in $INSTANCES; do
|
||||
NOW=$(perl -e "print time();")
|
||||
|
||||
echo ""
|
||||
echo '<<<db2_version:sep(1)>>>'
|
||||
DBVERSION=$(su - "${INSTANCE}" -c "db2 get snapshot for dbm" | grep -e 'Product name' -e 'Service level' | awk -v FS='=' '{print $2}' | sed 'N;s/\n/,/g' | sed 's/ //g')
|
||||
echo "$INSTANCE" "$DBVERSION"
|
||||
VERSION_NUMBER=$(echo "$DBVERSION" | sed -e 's/DB2v\(.*\),.*/\1/' | awk -v FS="." '{print $1"."$2}')
|
||||
|
||||
DBS=$(su - "${INSTANCE}" -c "db2 list active databases" | grep 'Database name' | awk '{ print $NF }')
|
||||
|
||||
DB_PORT='port 0'
|
||||
GET_PORT=1
|
||||
for DB in $DBS; do
|
||||
if [ 1 -eq $GET_PORT ] ; then
|
||||
# Each database in an instance has the same port information
|
||||
db2_tcp_service=$(su - "${INSTANCE}" -c "db2 -x get dbm cfg" | grep "TCP/IP Service" | awk -v FS='=' '{print $2}' | tr -d ' ')
|
||||
if ( grep "$db2_tcp_service" /etc/services | grep -q "^$db2_tcp_service " ); then
|
||||
DB_PORT='port '$(grep "$db2_tcp_service" /etc/services | grep "^$db2_tcp_service " | awk '{print $2}' | awk -v FS="/" '{print $1}')
|
||||
fi
|
||||
GET_PORT=0
|
||||
fi
|
||||
SCRIPT=$(readlink -f "$0")
|
||||
waitmax -s 9 10 su - "${INSTANCE}" -c "\"${SCRIPT}\" \"${INSTANCE}\" \"${DB}\" \"${VERSION_NUMBER}\" \"${NOW}\" \"${DB_PORT}\""
|
||||
done
|
||||
done
|
||||
else
|
||||
INSTANCE=$1
|
||||
DB=$2
|
||||
VERSION_NUMBER=$3
|
||||
NOW=$4
|
||||
DB_PORT=$5
|
||||
|
||||
function compare_version_greater_equal {
|
||||
GREATER_ONE=$(echo "$1 $2" | awk "{if ($1 >= $2) print $1; else print $2}")
|
||||
if [ "$GREATER_ONE" == "$1" ] ; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
millis_before=$(date +"%s%3N")
|
||||
if db2 +o connect to "$DB"; then
|
||||
millis_after=$(date +"%s%3N")
|
||||
millis_diff=$(( millis_after - millis_before ))
|
||||
|
||||
echo "<<<db2_connections>>>"
|
||||
echo "[[[$INSTANCE:$DB]]]"
|
||||
echo "$DB_PORT"
|
||||
echo "connections " | tr -d '\n'
|
||||
db2 -x "SELECT count(*)-1 FROM TABLE(mon_get_connection(CAST(NULL AS BIGINT), -2)) AS t"
|
||||
echo "latency ${millis_diff}"
|
||||
|
||||
echo "<<<db2_tablespaces>>>"
|
||||
echo "[[[$INSTANCE:$DB]]]"
|
||||
SQL="SELECT tbsp_name, tbsp_type, tbsp_state, tbsp_usable_size_kb, tbsp_total_size_kb, tbsp_used_size_kb, tbsp_free_size_kb FROM sysibmadm.tbsp_utilization WHERE tbsp_type = 'DMS' UNION ALL SELECT tu.tbsp_name, tu.tbsp_type, tu.tbsp_state, tu.tbsp_usable_size_kb, tu.tbsp_total_size_kb, tu.tbsp_used_size_kb, (cu.fs_total_size_kb - cu.fs_used_size_kb) AS tbsp_free_size_kb FROM sysibmadm.tbsp_utilization tu INNER JOIN ( SELECT tbsp_id, 1 AS fs_total_size_kb, 0 AS fs_used_size_kb FROM sysibmadm.container_utilization WHERE (fs_total_size_kb IS NULL OR fs_used_size_kb IS NULL) GROUP BY tbsp_id) cu ON (tu.tbsp_type = 'SMS' AND tu.tbsp_id = cu.tbsp_id) UNION ALL SELECT tu.tbsp_name, tu.tbsp_type, tu.tbsp_state, tu.tbsp_usable_size_kb, tu.tbsp_total_size_kb, tu.tbsp_used_size_kb, (cu.fs_total_size_kb - cu.fs_used_size_kb) AS tbsp_free_size_kb FROM sysibmadm.tbsp_utilization tu INNER JOIN ( SELECT tbsp_id, SUM(fs_total_size_kb) AS fs_total_size_kb, SUM(fs_used_size_kb) AS fs_used_size_kb FROM sysibmadm.container_utilization WHERE (fs_total_size_kb IS NOT NULL AND fs_used_size_kb IS NOT NULL) GROUP BY tbsp_id) cu ON (tu.tbsp_type = 'SMS' AND tu.tbsp_id = cu.tbsp_id)"
|
||||
db2 "${SQL}" | awk '{print $1" "$2" "$3" "$4" "$5" "$6" "$7}' | sed -e '/^[ ]*$/d' -e '/^-/d' -e '/selected/d'
|
||||
|
||||
echo "<<<db2_counters>>>"
|
||||
echo "TIMESTAMP $NOW"
|
||||
echo "$INSTANCE:$DB deadlocks " | tr -d '\n'
|
||||
db2 -x "SELECT deadlocks from sysibmadm.snapdb" | tr -d ' '
|
||||
echo "$INSTANCE:$DB lockwaits " | tr -d '\n'
|
||||
db2 -x "SELECT lock_waits from sysibmadm.snapdb" | tr -d ' '
|
||||
echo "$INSTANCE:$DB sortoverflows " | tr -d '\n'
|
||||
db2 -x "SELECT sort_overflows from sysibmadm.snapdb" | tr -d ' '
|
||||
|
||||
echo "<<<db2_logsizes>>>"
|
||||
echo "TIMESTAMP $NOW"
|
||||
echo "[[[$INSTANCE:$DB]]]"
|
||||
echo "usedspace " | tr -d '\n'
|
||||
db2 -x "SELECT total_log_used from sysibmadm.snapdb" | tr -d ' '
|
||||
db2 -x "SELECT NAME, VALUE FROM SYSIBMADM.DBCFG WHERE NAME IN ('logfilsiz','logprimary','logsecond')"| awk '{print $1" "$2}'
|
||||
|
||||
echo "<<<db2_bp_hitratios>>>"
|
||||
echo "[[[$INSTANCE:$DB]]]"
|
||||
db2 "SELECT SUBSTR(BP_NAME,1,14) AS BP_NAME, TOTAL_HIT_RATIO_PERCENT, DATA_HIT_RATIO_PERCENT, INDEX_HIT_RATIO_PERCENT, XDA_HIT_RATIO_PERCENT FROM SYSIBMADM.BP_HITRATIO" | grep -v "selected." | sed -e '/^$/d' -e '/^-/d'
|
||||
|
||||
echo "<<<db2_sort_overflow>>>"
|
||||
echo "[[[$INSTANCE:$DB]]]"
|
||||
db2 -x "get snapshot for database on $DB" | grep -e "^Total sorts" -e "^Sort overflows" | tr -d '='
|
||||
|
||||
echo "<<<db2_backup>>>"
|
||||
echo "[[[$INSTANCE:$DB]]]"
|
||||
if compare_version_greater_equal "$VERSION_NUMBER" 10.5; then
|
||||
# MON_GET_DATBASE(-2) gets information of all active members
|
||||
db2 -x "select LAST_BACKUP from TABLE (MON_GET_DATABASE(-2))" | grep -v "selected." | tail -n 1
|
||||
else
|
||||
db2 -x "select SQLM_ELM_LAST_BACKUP from table(SNAPSHOT_DATABASE( cast( null as VARCHAR(255)), cast(null as int))) as ref" | grep -v "selected." | tail -n 1
|
||||
fi
|
||||
|
||||
# disconnect from database
|
||||
db2 connect reset > /dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,55 @@
|
|||
#!/bin/bash
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2018 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# $REMOTE is exported from check_mk_agent.linux
|
||||
|
||||
if type docker > /dev/null 2>&1; then
|
||||
NODE_NAME=$(docker info --format "{{json .Name}}")
|
||||
|
||||
# For the container status, we want information about *all* containers
|
||||
for CONTAINER_ID in $(docker container ls -q --all); do
|
||||
echo "<<<<${CONTAINER_ID}>>>>"
|
||||
docker inspect "$CONTAINER_ID" \
|
||||
--format='{{println "<<<docker_container_status>>>"}}{{json .State}}{{println}}{{println "<<<docker_container_node_name>>>"}}{{println '"$NODE_NAME"'}}{{println "<<<docker_container_labels>>>"}}{{json .Config.Labels}}{{println}}{{println "<<<docker_container_network>>>"}}{{json .NetworkSettings}}{{println}}'
|
||||
|
||||
if [ "$(docker inspect -f '{{.State.Running}}' "$CONTAINER_ID")" = "true" ]; then
|
||||
# Is there a regular agent available in the container? Use it!
|
||||
#
|
||||
# Otherwise execute the agent of the node in the context of the container.
|
||||
# Using this approach we should always get at least basic information from
|
||||
# the container.
|
||||
# Once it comes to plugins and custom configuration the user needs to use
|
||||
# a little more complex setup. Have a look at the documentation.
|
||||
AGENT_PATH=$(docker container exec "$CONTAINER_ID" bash -c "type check_mk_agent" 2>/dev/null) || AGENT_PATH=
|
||||
if [ -n "$AGENT_PATH" ]; then
|
||||
docker container exec --env "REMOTE=$REMOTE" "$CONTAINER_ID" check_mk_agent
|
||||
elif docker container exec "$CONTAINER_ID" which bash >/dev/null 2>&1; then
|
||||
docker container exec --env MK_FROM_NODE=1 --env "REMOTE=$REMOTE" -i "$CONTAINER_ID" bash < "$0"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "<<<<>>>>"
|
||||
done
|
||||
fi
|
33
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_filehandler
Executable file
33
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_filehandler
Executable file
|
@ -0,0 +1,33 @@
|
|||
#!/bin/bash
|
||||
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
FILE=/proc/sys/fs/file-nr
|
||||
|
||||
echo '<<<filehandler>>>'
|
||||
if [ -a $FILE ]; then
|
||||
cat $FILE
|
||||
fi
|
||||
|
5
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_haproxy.freebsd
Executable file
5
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_haproxy.freebsd
Executable file
|
@ -0,0 +1,5 @@
|
|||
if [ -r /var/run/haproxy.stat ]; then
|
||||
echo "<<<haproxy:sep(44)>>>"
|
||||
echo "show stat" | socat - UNIX-CONNECT:/var/run/haproxy.sock
|
||||
fi
|
||||
|
296
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_informix
Executable file
296
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_informix
Executable file
|
@ -0,0 +1,296 @@
|
|||
#!/bin/bash
|
||||
# Monitor status of LUNs on HP-UX
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# Make ENV-VARs avail for subshells
|
||||
set -a
|
||||
|
||||
# .--helper--------------------------------------------------------------.
|
||||
# | _ _ |
|
||||
# | | |__ ___| |_ __ ___ _ __ |
|
||||
# | | '_ \ / _ \ | '_ \ / _ \ '__| |
|
||||
# | | | | | __/ | |_) | __/ | |
|
||||
# | |_| |_|\___|_| .__/ \___|_| |
|
||||
# | |_| |
|
||||
# '----------------------------------------------------------------------'
|
||||
|
||||
|
||||
function do_check () {
|
||||
# $1:section, $2:excludelist
|
||||
if echo "$2" | grep -qe "${1}"; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function sql () {
|
||||
db="sysmaster"
|
||||
sqltxt="$1"
|
||||
dbaccess_par=
|
||||
export DBDELIMITER="|"
|
||||
echo "$sqltxt" | dbaccess ${db}
|
||||
}
|
||||
|
||||
|
||||
function set_excludes () {
|
||||
excludes=""
|
||||
if [ "$EXCLUDES" = "ALL" ]; then
|
||||
excludes="$all_sections"
|
||||
global_exclude=true
|
||||
elif [ ! -z "$EXCLUDES" ]; then
|
||||
excludes=$EXCLUDES
|
||||
global_exclude=true
|
||||
else
|
||||
global_exclude=false
|
||||
fi
|
||||
|
||||
if [ "$global_exclude" = "false" ]; then
|
||||
excludes_i="EXCLUDES_${1}"
|
||||
if [ "${!excludes_i}" = "ALL" ]; then
|
||||
excludes="$all_sections"
|
||||
elif [ ! -z "${!excludes_i}" ]; then
|
||||
excludes=${!excludes_i}
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
#.
|
||||
# .--sqls----------------------------------------------------------------.
|
||||
# | _ |
|
||||
# | ___ __ _| |___ |
|
||||
# | / __|/ _` | / __| |
|
||||
# | \__ \ (_| | \__ \ |
|
||||
# | |___/\__, |_|___/ |
|
||||
# | |_| |
|
||||
# '----------------------------------------------------------------------'
|
||||
|
||||
|
||||
all_sections="sessions locks tabextents dbspaces logusage"
|
||||
|
||||
|
||||
function informix_status(){
|
||||
echo "<<<informix_status:sep(58)>>>"
|
||||
echo "[[[$INFORMIXSERVER/$SERVERNUM]]]"
|
||||
$INFORMIXDIR/bin/onstat - >/dev/null 2>&1
|
||||
state=$?
|
||||
echo "Status:"$state
|
||||
$INFORMIXDIR/bin/onstat -g dis
|
||||
port=$(grep $INFORMIXSERVER /etc/services)
|
||||
echo "PORT:"$port
|
||||
}
|
||||
|
||||
|
||||
function informix_sessions(){
|
||||
echo "<<<informix_sessions>>>"
|
||||
echo "[[[$INFORMIXSERVER/$SERVERNUM]]]"
|
||||
# don't count our own session
|
||||
sql "select 'SESSIONS', (count(*)-1)::int from syssessions"
|
||||
}
|
||||
|
||||
|
||||
function informix_locks(){
|
||||
echo "<<<informix_locks>>>"
|
||||
echo "[[[$INFORMIXSERVER/$SERVERNUM]]]"
|
||||
# don't count our own session
|
||||
sql "select 'LOCKS', (count(*)-1)::int, type from syslocks group by type"
|
||||
}
|
||||
|
||||
|
||||
function informix_tabextents(){
|
||||
echo "<<<informix_tabextents>>>"
|
||||
echo "[[[$INFORMIXSERVER/$SERVERNUM]]]"
|
||||
sql "select first 10
|
||||
'TABEXTENTS',
|
||||
trim(n.dbsname) db,
|
||||
trim(n.tabname) tab,
|
||||
h.nextns extents,
|
||||
nrows
|
||||
from sysptnhdr h, systabnames n
|
||||
where h.partnum = n.partnum
|
||||
and nrows > 0
|
||||
and n.dbsname not in ( 'sysadmin', 'sysuser', 'sysutils', 'sysmaster' )
|
||||
and n.tabname not like 'sys%'
|
||||
order by extents desc"
|
||||
}
|
||||
|
||||
|
||||
function informix_dbspaces(){
|
||||
echo "<<<informix_dbspaces>>>"
|
||||
echo "[[[$INFORMIXSERVER/$SERVERNUM]]]"
|
||||
sql "select
|
||||
trim(sd.name) || ' DBSPACE',
|
||||
sd.dbsnum,
|
||||
sd.is_temp,
|
||||
sd.flags,
|
||||
'CHUNK',
|
||||
sc.fname,
|
||||
sc.pagesize,
|
||||
sc.chksize,
|
||||
sc.nfree,
|
||||
sc.flags,
|
||||
trim(sc.mfname),
|
||||
sc.mflags
|
||||
from sysdbspaces sd, syschunks sc
|
||||
where sd.dbsnum = sc.dbsnum
|
||||
-- NO SBSPACE CURRENTLY
|
||||
and sd.is_sbspace = 0
|
||||
order by sd.name"
|
||||
}
|
||||
|
||||
|
||||
function informix_logusage(){
|
||||
echo "<<<informix_logusage>>>"
|
||||
echo "[[[$INFORMIXSERVER/$SERVERNUM]]]"
|
||||
sql "select 'LOGUSAGE',
|
||||
number,
|
||||
sh_pagesize,
|
||||
size,
|
||||
used,
|
||||
flags,
|
||||
'is_used:'||is_used,
|
||||
'is_current:'||is_current,
|
||||
'is_backed_up:'||is_backed_up,
|
||||
'is_new:'||is_new,
|
||||
'is_archived:'||is_archived,
|
||||
'is_temp:'||is_temp,
|
||||
'is_pre_dropped:'||is_pre_dropped
|
||||
from syslogs, sysshmvals
|
||||
order by number"
|
||||
}
|
||||
|
||||
|
||||
#.
|
||||
# .--config--------------------------------------------------------------.
|
||||
# | __ _ |
|
||||
# | ___ ___ _ __ / _(_) __ _ |
|
||||
# | / __/ _ \| '_ \| |_| |/ _` | |
|
||||
# | | (_| (_) | | | | _| | (_| | |
|
||||
# | \___\___/|_| |_|_| |_|\__, | |
|
||||
# | |___/ |
|
||||
# '----------------------------------------------------------------------'
|
||||
|
||||
|
||||
# Config opts:
|
||||
# - oninit-path; Default is empty, which means autodetection:
|
||||
# ONINIT_PATH=<path to oninit-binary>
|
||||
# - Excluding sections ("status sessions locks tabextents dbspaces logusage"):
|
||||
# EXCLUDES_INFORMIX_INSTANCE="SECTION SECTION ..."
|
||||
# EXCLUDES_INFORMIX_INSTANCE=ALL
|
||||
# EXCLUDES="SECTION SECTION ..."
|
||||
# EXCLUDES=ALL
|
||||
|
||||
|
||||
if [ -f "$MK_CONFDIR/informix.cfg" ]; then
|
||||
. $MK_CONFDIR/informix.cfg
|
||||
fi
|
||||
|
||||
|
||||
if [ -z "$ONINIT_PATH" -o ! -x "$ONINIT_PATH" ]; then
|
||||
ONINIT=$(UNIX95=true ps ax | grep oninit | grep -v grep | head -1 | awk '{print $1 " " $5}')
|
||||
if [ -z "$ONINIT" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
ONINIT_PATH=${ONINIT#* }
|
||||
ONINIT_PID=${ONINIT% *}
|
||||
case "$ONINIT_PATH" in
|
||||
/*)
|
||||
;;
|
||||
*) # BUG not platform independent!
|
||||
ONINIT_PATH=$(ls -l /proc/$ONINIT_PID/exe 2>/dev/null| sed 's/.* //')
|
||||
;;
|
||||
esac
|
||||
|
||||
# If not set in config or not found we end up here
|
||||
if [ -z "$ONINIT_PATH" -o ! -f "$ONINIT_PATH" ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
#.
|
||||
# .--main----------------------------------------------------------------.
|
||||
# | _ |
|
||||
# | _ __ ___ __ _(_)_ __ |
|
||||
# | | '_ ` _ \ / _` | | '_ \ |
|
||||
# | | | | | | | (_| | | | | | |
|
||||
# | |_| |_| |_|\__,_|_|_| |_| |
|
||||
# | |
|
||||
# '----------------------------------------------------------------------'
|
||||
|
||||
|
||||
for IDSENV in $( export INFORMIXDIR=${ONINIT_PATH%/bin*}
|
||||
$INFORMIXDIR/bin/onstat -g dis | \
|
||||
egrep '^Server[ ]*:|^Server Number[ ]*:|^INFORMIX|^SQLHOSTS|^ONCONFIG' | \
|
||||
sed -e 's/Server Number/SERVERNUM/' \
|
||||
-e 's/Server/INFORMIXSERVER/' \
|
||||
-e 's/SQLHOSTS/INFORMIXSQLHOSTS/' \
|
||||
-e 's/[ ]*:[ ]*/=/' | \
|
||||
tr '\n' ';' | \
|
||||
sed -e 's/;$/\n/' -e 's/;\(INFORMIXSERVER=[^;]*;\)/\n\1/g'
|
||||
|
||||
) ; do
|
||||
(
|
||||
# Set environment
|
||||
eval $IDSENV
|
||||
PATH=$INFORMIXDIR/bin:$PATH
|
||||
|
||||
# try to set them via 'onstat -g env' otherwise
|
||||
# DB HAS TO BE RUNNING
|
||||
if [ -z "$INFORMIXSQLHOSTS" -o -z "$ONCONFIG" ]; then
|
||||
onstat -g env | egrep -e '^INFORMIXSQLHOSTS' \
|
||||
-e '^ONCONFIG' | \
|
||||
sed -e 's/[ ][ ]*/=/'
|
||||
fi
|
||||
|
||||
informix_status
|
||||
|
||||
set_excludes $INFORMIXSERVER
|
||||
|
||||
if do_check "sessions" "$excludes"; then
|
||||
informix_sessions
|
||||
fi
|
||||
|
||||
if do_check "locks" "$excludes"; then
|
||||
informix_locks
|
||||
fi
|
||||
|
||||
if do_check "tabextents" "$excludes"; then
|
||||
informix_tabextents
|
||||
fi
|
||||
|
||||
if do_check "dbspaces" "$excludes"; then
|
||||
informix_dbspaces
|
||||
fi
|
||||
|
||||
if do_check "logusage" "$excludes"; then
|
||||
informix_logusage
|
||||
fi
|
||||
)
|
||||
done
|
||||
|
357
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_inotify
Executable file
357
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_inotify
Executable file
|
@ -0,0 +1,357 @@
|
|||
#!/usr/bin/python
|
||||
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2016 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import signal
|
||||
import ConfigParser
|
||||
|
||||
try:
|
||||
# TODO: We should probably ship this package.
|
||||
import pyinotify # pylint: disable=import-error
|
||||
except:
|
||||
sys.stderr.write("Error: Python plugin pyinotify is not installed")
|
||||
sys.exit(1)
|
||||
|
||||
def usage():
|
||||
sys.stdout.write("Usage: mk_inotify [-g]\n")
|
||||
sys.stdout.write(" -g: run in foreground\n\n")
|
||||
|
||||
# Available options:
|
||||
# -g: run in foreground
|
||||
opt_foreground = False
|
||||
if len(sys.argv) == 2 and sys.argv[1] == "-g":
|
||||
opt_foreground = True
|
||||
|
||||
mk_confdir = os.getenv("MK_CONFDIR") or "/etc/check_mk"
|
||||
mk_vardir = os.getenv("MK_VARDIR") or "/var/lib/check_mk_agent"
|
||||
|
||||
config_filename = mk_confdir + "/mk_inotify.cfg"
|
||||
configured_paths = mk_vardir + "/mk_inotify.configured"
|
||||
pid_filename = mk_vardir + "/mk_inotify.pid"
|
||||
|
||||
|
||||
config = ConfigParser.SafeConfigParser({})
|
||||
if not os.path.exists(config_filename):
|
||||
sys.exit(0)
|
||||
config_mtime = os.stat(config_filename).st_mtime
|
||||
config.read(config_filename)
|
||||
|
||||
# Configurable in Agent Bakery
|
||||
heartbeat_timeout = config.getint("global", "heartbeat_timeout")
|
||||
write_interval = config.getint("global", "write_interval")
|
||||
max_messages_per_interval = config.getint("global", "max_messages_per_interval")
|
||||
stats_retention = config.getint("global", "stats_retention")
|
||||
config.remove_section("global")
|
||||
|
||||
def output_data():
|
||||
sys.stdout.write("<<<inotify:sep(9)>>>\n")
|
||||
if os.path.exists(configured_paths):
|
||||
sys.stdout.write(file(configured_paths).read())
|
||||
|
||||
now = time.time()
|
||||
for dirpath, _unused_dirnames, filenames in os.walk(mk_vardir):
|
||||
for filename in filenames:
|
||||
if filename.startswith("mk_inotify.stats"):
|
||||
try:
|
||||
the_file = "%s/%s" % (dirpath, filename)
|
||||
filetime = os.stat(the_file).st_mtime
|
||||
file_age = now - filetime
|
||||
if file_age > 5:
|
||||
sys.stdout.write(file(the_file).read())
|
||||
if file_age > stats_retention:
|
||||
os.unlink(the_file)
|
||||
except:
|
||||
pass
|
||||
break
|
||||
|
||||
# Check if another mk_inotify process is already running
|
||||
if os.path.exists(pid_filename):
|
||||
pid = file(pid_filename).read()
|
||||
proc_cmdline = "/proc/%s/cmdline" % pid
|
||||
if os.path.exists(proc_cmdline):
|
||||
cmdline = file(proc_cmdline).read()
|
||||
cmdline_tokens = cmdline.split("\0")
|
||||
if "mk_inotify" in cmdline_tokens[1]:
|
||||
# Another mk_notify process is already running..
|
||||
# Simply output the current statistics and exit
|
||||
output_data()
|
||||
|
||||
# The pidfile is also the heartbeat file for the running process
|
||||
os.utime(pid_filename, None)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
# .--Fork----------------------------------------------------------------.
|
||||
# | _____ _ |
|
||||
# | | ___|__ _ __| | __ |
|
||||
# | | |_ / _ \| '__| |/ / |
|
||||
# | | _| (_) | | | < |
|
||||
# | |_| \___/|_| |_|\_\ |
|
||||
# | |
|
||||
# +----------------------------------------------------------------------+
|
||||
# Reaching this point means that no mk_inotify is currently running
|
||||
|
||||
if not opt_foreground:
|
||||
try:
|
||||
pid = os.fork()
|
||||
if pid > 0:
|
||||
sys.exit(0)
|
||||
# Decouple from parent environment
|
||||
os.chdir("/")
|
||||
os.umask(0)
|
||||
os.setsid()
|
||||
|
||||
# Close all fd
|
||||
for fd in range(0, 256):
|
||||
try:
|
||||
os.close(fd)
|
||||
except OSError:
|
||||
pass
|
||||
except Exception, e:
|
||||
sys.stderr.write("Error forking mk_inotify: %s" % e)
|
||||
|
||||
# Save pid of working process.
|
||||
file(pid_filename, "w").write("%d" % os.getpid())
|
||||
#.
|
||||
# .--Main----------------------------------------------------------------.
|
||||
# | __ __ _ |
|
||||
# | | \/ | __ _(_)_ __ |
|
||||
# | | |\/| |/ _` | | '_ \ |
|
||||
# | | | | | (_| | | | | | |
|
||||
# | |_| |_|\__,_|_|_| |_| |
|
||||
# | |
|
||||
# +----------------------------------------------------------------------+
|
||||
|
||||
folder_configs = {} # Computed configuration
|
||||
output = [] # Data to be written to disk
|
||||
def get_watched_files():
|
||||
files = set([])
|
||||
for folder, attributes in folder_configs.items():
|
||||
for filenames in attributes["monitor_files"].values():
|
||||
for filename in filenames:
|
||||
files.add("configured\tfile\t%s/%s" % (folder, filename))
|
||||
if attributes.get("monitor_all"):
|
||||
files.add("configured\tfolder\t%s" % (folder))
|
||||
return files
|
||||
|
||||
def wakeup_handler(signum, frame):
|
||||
global output
|
||||
if output:
|
||||
if opt_foreground:
|
||||
sys.stdout.write("%s\n" % "\n".join(output))
|
||||
sys.stdout.write("%s\n" % "\n".join(get_watched_files()))
|
||||
else:
|
||||
filename = "mk_inotify.stats.%d" % time.time()
|
||||
file("%s/%s" % (mk_vardir, filename), "w").write("\n".join(output)+"\n")
|
||||
output = []
|
||||
|
||||
# Check if configuration has changed -> restart
|
||||
if (config_mtime != os.stat(config_filename).st_mtime):
|
||||
os.execv(__file__, sys.argv)
|
||||
|
||||
# Exit on various instances
|
||||
if not opt_foreground:
|
||||
if not os.path.exists(pid_filename): # pidfile is missing
|
||||
sys.exit(0)
|
||||
if time.time() - os.stat(pid_filename).st_mtime > heartbeat_timeout: # heartbeat timeout
|
||||
sys.exit(0)
|
||||
if os.getpid() != int(file(pid_filename).read()): # pidfile differs
|
||||
sys.exit(0)
|
||||
|
||||
update_watched_folders()
|
||||
signal.alarm(write_interval)
|
||||
|
||||
def do_output(what, event):
|
||||
if event.dir:
|
||||
return # Only monitor files
|
||||
|
||||
if len(output) > max_messages_per_interval:
|
||||
last_message = "warning\tMaximum messages reached: %d per %d seconds" % \
|
||||
(max_messages_per_interval, write_interval)
|
||||
if output[-1] != last_message:
|
||||
output.append(last_message)
|
||||
return
|
||||
|
||||
path = event.path
|
||||
path_config = folder_configs.get(path)
|
||||
if not path_config:
|
||||
return # shouldn't happen, maybe on subfolders (not supported)
|
||||
|
||||
filename = os.path.basename(event.pathname)
|
||||
if what in path_config["monitor_all"] or\
|
||||
filename in path_config["monitor_files"].get(what, []):
|
||||
line = "%d\t%s\t%s" % (time.time(), what, event.pathname)
|
||||
if map_events[what][1]: # Check if filestats are enabled
|
||||
try:
|
||||
stats = os.stat(event.pathname)
|
||||
line += "\t%d\t%d" % (stats.st_size, stats.st_mtime)
|
||||
except Exception:
|
||||
pass
|
||||
output.append(line)
|
||||
if opt_foreground:
|
||||
sys.stdout.write("%s\n" % line)
|
||||
|
||||
|
||||
map_events = {
|
||||
# Mode Mask Report_filestats (currently unused)
|
||||
"access" : (pyinotify.IN_ACCESS, False), # pylint: disable=no-member
|
||||
"open" : (pyinotify.IN_OPEN, False), # pylint: disable=no-member
|
||||
"create" : (pyinotify.IN_CREATE, False), # pylint: disable=no-member
|
||||
"delete" : (pyinotify.IN_DELETE, False), # pylint: disable=no-member
|
||||
"modify" : (pyinotify.IN_MODIFY, False), # pylint: disable=no-member
|
||||
"movedto" : (pyinotify.IN_MOVED_TO, False), # pylint: disable=no-member
|
||||
"movedfrom": (pyinotify.IN_MOVED_FROM, False), # pylint: disable=no-member
|
||||
"moveself" : (pyinotify.IN_MOVE_SELF, False), # pylint: disable=no-member
|
||||
}
|
||||
|
||||
class NotifyEventHandler(pyinotify.ProcessEvent):
|
||||
def process_IN_MOVED_TO(self, event):
|
||||
do_output("movedto", event)
|
||||
|
||||
def process_IN_MOVED_FROM(self, event):
|
||||
do_output("movedfrom", event)
|
||||
|
||||
def process_IN_MOVE_SELF(self, event):
|
||||
do_output("moveself", event)
|
||||
# def process_IN_CLOSE_NOWRITE(self, event):
|
||||
# print "CLOSE_NOWRITE event:", event.pathname
|
||||
#
|
||||
# def process_IN_CLOSE_WRITE(self, event):
|
||||
# print "CLOSE_WRITE event:", event.pathname
|
||||
|
||||
def process_IN_CREATE(self, event):
|
||||
do_output("create", event)
|
||||
|
||||
def process_IN_DELETE(self, event):
|
||||
do_output("delete", event)
|
||||
|
||||
def process_IN_MODIFY(self, event):
|
||||
do_output("modify", event)
|
||||
|
||||
def process_IN_OPEN(self, event):
|
||||
do_output("open", event)
|
||||
|
||||
|
||||
# Watch manager
|
||||
wm = pyinotify.WatchManager()
|
||||
def update_watched_folders():
|
||||
for folder, attributes in folder_configs.items():
|
||||
if attributes.get("watch_descriptor"):
|
||||
if not wm.get_path(attributes["watch_descriptor"].get(folder)):
|
||||
del attributes["watch_descriptor"]
|
||||
else:
|
||||
if os.path.exists(folder):
|
||||
new_wd = wm.add_watch(folder, attributes["mask"], rec=True)
|
||||
if new_wd.get(folder) > 0:
|
||||
attributes["watch_descriptor"] = new_wd
|
||||
|
||||
|
||||
def main():
|
||||
# Read config
|
||||
|
||||
for section in config.sections():
|
||||
section_tokens = section.split("|")
|
||||
|
||||
folder = section_tokens[0]
|
||||
folder_configs.setdefault(folder, {"add_modes": {},
|
||||
"del_modes": {},
|
||||
"all_add_modes": set([]),
|
||||
"all_del_modes": set([])})
|
||||
|
||||
files = None
|
||||
if len(section_tokens) > 1:
|
||||
files = set(section_tokens[1:])
|
||||
|
||||
add_modes = set([])
|
||||
del_modes = set([])
|
||||
for key, value in config.items(section):
|
||||
if key in map_events:
|
||||
if value == "1":
|
||||
add_modes.add(key)
|
||||
else:
|
||||
del_modes.add(key)
|
||||
|
||||
if files:
|
||||
for mode in add_modes:
|
||||
folder_configs[folder]["add_modes"].setdefault(mode, set([]))
|
||||
folder_configs[folder]["add_modes"][mode].update(files)
|
||||
for mode in del_modes:
|
||||
folder_configs[folder]["del_modes"].setdefault(mode, set([]))
|
||||
folder_configs[folder]["del_modes"][mode].update(files)
|
||||
else:
|
||||
folder_configs[folder]["all_add_modes"].update(add_modes)
|
||||
folder_configs[folder]["all_del_modes"].update(del_modes)
|
||||
|
||||
|
||||
# Evaluate config
|
||||
for folder, attributes in folder_configs.items():
|
||||
required_modes = set([])
|
||||
for mode in attributes["add_modes"].keys():
|
||||
if mode not in attributes["all_del_modes"]:
|
||||
required_modes.add(mode)
|
||||
|
||||
files_to_monitor = {}
|
||||
skip_modes = set([])
|
||||
for mode in required_modes:
|
||||
files_to_monitor.setdefault(mode, set([]))
|
||||
files_to_monitor[mode].update(attributes["add_modes"][mode])
|
||||
files_to_monitor[mode] -= attributes["del_modes"].get(mode, set([]))
|
||||
if not files_to_monitor[mode]:
|
||||
skip_modes.add(mode)
|
||||
|
||||
attributes["monitor_files"] = files_to_monitor
|
||||
attributes["monitor_all"] = attributes["all_add_modes"] - attributes["all_del_modes"]
|
||||
attributes["modes"] = required_modes - skip_modes
|
||||
|
||||
# Determine mask
|
||||
attributes["mask"] = 0
|
||||
for mode in attributes["modes"]:
|
||||
attributes["mask"] |= map_events[mode][0]
|
||||
for mode in attributes["monitor_all"]:
|
||||
attributes["mask"] |= map_events[mode][0]
|
||||
|
||||
update_watched_folders()
|
||||
if opt_foreground:
|
||||
import pprint
|
||||
sys.stdout.write(pprint.pformat(folder_configs))
|
||||
|
||||
# Save monitored file/folder information specified in mk_inotify.cfg
|
||||
file(configured_paths, "w").write("\n".join(get_watched_files())+"\n")
|
||||
|
||||
# Event handler
|
||||
eh = NotifyEventHandler()
|
||||
notifier = pyinotify.Notifier(wm, eh)
|
||||
|
||||
# Wake up every few seconds, check heartbeat and write data to disk
|
||||
signal.signal(signal.SIGALRM, wakeup_handler)
|
||||
signal.alarm(write_interval)
|
||||
|
||||
notifier.loop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
69
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_inventory.aix
Executable file
69
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_inventory.aix
Executable file
|
@ -0,0 +1,69 @@
|
|||
#!/bin/bash
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# Run and *send* only once every 4 hours
|
||||
INTERVAL=14400
|
||||
|
||||
FLAGFILE=$MK_VARDIR/mk_inventory.last.$REMOTE
|
||||
NOW=$(date +%s)
|
||||
UNTIL=$((NOW + INTERVAL + 600))
|
||||
|
||||
#check if flagfile exits
|
||||
if [ -e "$FLAGFILE" ]; then
|
||||
LAST_RUN=$(cat $FLAGFILE)
|
||||
else
|
||||
#First run of the script
|
||||
LAST_RUN=0
|
||||
fi
|
||||
|
||||
if [ $(( NOW - LAST_RUN )) -ge $INTERVAL ]
|
||||
then
|
||||
echo $NOW > $FLAGFILE
|
||||
|
||||
# List of installed AIX packages
|
||||
if type lslpp >/dev/null; then
|
||||
echo "<<<aix_packages:sep(58):persist($UNTIL)>>>"
|
||||
lslpp -c -L
|
||||
fi
|
||||
|
||||
if type oslevel > /dev/null; then
|
||||
# base level of the system
|
||||
echo "<<<aix_baselevel:persist($UNTIL)>>>"
|
||||
oslevel
|
||||
|
||||
# list the known service packs on a system
|
||||
echo "<<<aix_service_packs:persist($UNTIL)>>>"
|
||||
oslevel -sq
|
||||
fi
|
||||
|
||||
# If you run the prtconf command without any flags, it displays the system model, machine serial,
|
||||
# processor type, number of processors, processor clock speed, cpu type, total memory size, network information, filesystem
|
||||
# information, paging space information, and devices information.
|
||||
if type prtconf >/dev/null ; then
|
||||
echo "<<<prtconf:sep(58):persist($UNTIL)>>>"
|
||||
prtconf
|
||||
fi
|
||||
fi
|
||||
|
100
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_inventory.linux
Executable file
100
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_inventory.linux
Executable file
|
@ -0,0 +1,100 @@
|
|||
#!/bin/bash
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# Run and *send* only once every __ seconds
|
||||
. $MK_CONFDIR/mk_inventory.cfg 2>/dev/null || true
|
||||
|
||||
# Default to four hours
|
||||
INTERVAL=${INVENTORY_INTERVAL:-14400}
|
||||
|
||||
FLAGFILE=$MK_VARDIR/mk_inventory.last.$REMOTE
|
||||
LAST_RUN=$(stat -c %Y $FLAGFILE)
|
||||
NOW=$(date +%s)
|
||||
UNTIL=$((NOW + INTERVAL + 600))
|
||||
|
||||
if [ $(( NOW - LAST_RUN )) -ge $INTERVAL ]
|
||||
then
|
||||
touch $FLAGFILE
|
||||
|
||||
# List of DEB packages
|
||||
if type dpkg-query >/dev/null; then
|
||||
echo "<<<lnx_packages:sep(124):persist($UNTIL)>>>"
|
||||
dpkg-query --show --showformat='${Package}|${Version}|${Architecture}|deb|-|${Summary}|${Status}\n'
|
||||
fi
|
||||
|
||||
# List of RPM packages in same format
|
||||
if type rpm >/dev/null; then
|
||||
echo "<<<lnx_packages:sep(9):persist($UNTIL)>>>"
|
||||
rpm -qa --qf '%{NAME}\t%{VERSION}\t%{ARCH}\trpm\t%{RELEASE}\t%{SUMMARY}\t-\n'
|
||||
fi
|
||||
|
||||
# List Gentoo packages
|
||||
if type equery >/dev/null; then
|
||||
echo "<<<lnx_packages:sep(124):persist($UNTIL)>>>"
|
||||
equery -C list --format '$category/$name|$fullversion|$mask2|ebuild|Repository $repo|installed' \* | head -n -1
|
||||
fi
|
||||
|
||||
# Information about distribution
|
||||
echo "<<<lnx_distro:sep(124):persist($UNTIL)>>>"
|
||||
for f in {/etc/{oracle-release,debian_version,gentoo-release,lsb-release,redhat-release,SuSE-release,os-release},/usr/share/cma/version} ; do
|
||||
if [ -e $f ] ; then
|
||||
echo "[[[$f]]]"
|
||||
tr \\n \| < $f | sed 's/|$//' ; echo
|
||||
fi
|
||||
done
|
||||
|
||||
# CPU Information. We need just the first one
|
||||
if [ -e /proc/cpuinfo ] ; then
|
||||
echo "<<<lnx_cpuinfo:sep(58):persist($UNTIL)>>>"
|
||||
sed 's/[[:space:]]*:[[:space:]]*/:/' < /proc/cpuinfo
|
||||
fi
|
||||
|
||||
# Information about main board, memory, etc.
|
||||
if type dmidecode >/dev/null ; then
|
||||
echo "<<<dmidecode:sep(58):persist($UNTIL)>>>"
|
||||
dmidecode -q | sed 's/\t/:/g'
|
||||
fi
|
||||
|
||||
# Information about kernel architecture
|
||||
if type uname >/dev/null ; then
|
||||
echo "<<<lnx_uname:persist($UNTIL)>>>"
|
||||
uname -m
|
||||
uname -r
|
||||
fi
|
||||
if type lspci > /dev/null ; then
|
||||
echo "<<<lnx_video:sep(58):persist($UNTIL)>>>"
|
||||
lspci -v -s $(lspci | grep VGA | cut -d" " -f 1)
|
||||
fi
|
||||
|
||||
# Some networking information
|
||||
if type ip > /dev/null ; then
|
||||
echo "<<<lnx_ip_a:persist($UNTIL)>>>"
|
||||
ip a
|
||||
echo "<<<lnx_ip_r:persist($UNTIL)>>>"
|
||||
ip r
|
||||
fi
|
||||
|
||||
fi
|
||||
|
91
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_inventory.solaris
Executable file
91
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_inventory.solaris
Executable file
|
@ -0,0 +1,91 @@
|
|||
#!/bin/bash
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# Run and *send* only once every __ seconds
|
||||
. $MK_CONFDIR/mk_inventory.cfg 2>/dev/null || true
|
||||
|
||||
# Default to four hours
|
||||
INTERVAL=${INVENTORY_INTERVAL:-14400}
|
||||
|
||||
FLAGFILE=$MK_VARDIR/mk_inventory.last.$REMOTE
|
||||
if [ `uname -r` = "5.10" ]; then
|
||||
NOW=$(truss /usr/bin/date 2>&1 | grep ^time | awk -F"= " '{print $2}')
|
||||
else
|
||||
NOW=`date +%s`
|
||||
fi
|
||||
UNTIL=$((NOW + INTERVAL + 600))
|
||||
|
||||
#check if flagfile exits
|
||||
if [ -e "$FLAGFILE" ]; then
|
||||
LAST_RUN=$(cat $FLAGFILE)
|
||||
else
|
||||
#First run of the script
|
||||
LAST_RUN=0
|
||||
fi
|
||||
|
||||
if [ $(( NOW - LAST_RUN )) -ge $INTERVAL ]
|
||||
then
|
||||
echo $NOW > $FLAGFILE
|
||||
|
||||
echo "<<<solaris_uname:sep(61):persist($UNTIL)>>>"
|
||||
uname -X
|
||||
|
||||
if zoneadm list | grep global >/dev/null 2>&1
|
||||
then
|
||||
if type prtdiag > /dev/null; then
|
||||
echo "<<<solaris_prtdiag:sep(10):persist($UNTIL)>>>"
|
||||
if type sneep >/dev/null 2>&1; then
|
||||
SN=$(sneep -t serial)
|
||||
else
|
||||
SN=$(smbios -t SMB_TYPE_SYSTEM | grep 'Serial Number:' | awk '{print substr($0, index($0,$3))}')
|
||||
fi
|
||||
echo "SerialNumber: $SN"
|
||||
prtdiag -v
|
||||
fi
|
||||
|
||||
if type prtpicl > /dev/null; then
|
||||
echo "<<<solaris_prtpicl:persist($UNTIL)>>>"
|
||||
prtpicl -v
|
||||
fi
|
||||
fi
|
||||
|
||||
if type psrinfo > /dev/null; then
|
||||
echo "<<<solaris_psrinfo:persist($UNTIL)>>>"
|
||||
psrinfo -p -v
|
||||
fi
|
||||
|
||||
if type pkginfo >/dev/null ; then
|
||||
echo "<<<solaris_pkginfo:sep(58):persist($UNTIL)>>>"
|
||||
pkginfo -l
|
||||
fi
|
||||
|
||||
echo "<<<solaris_addresses:persist($UNTIL)>>>"
|
||||
ifconfig -a
|
||||
|
||||
echo "<<<solaris_routes:persist($UNTIL)>>>"
|
||||
netstat -nr
|
||||
|
||||
fi
|
||||
|
34
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_iptables
Executable file
34
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_iptables
Executable file
|
@ -0,0 +1,34 @@
|
|||
#!/bin/bash
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2017 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# iptables
|
||||
if type iptables-save > /dev/null
|
||||
then
|
||||
echo "<<<iptables>>>"
|
||||
# output filter configuration without table name, comments and
|
||||
# status data, i.e. lines beginning with '*', '#' or ':'.
|
||||
iptables-save -t filter | sed '/^[#*:]/d'
|
||||
fi
|
||||
|
523
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_jolokia
Executable file
523
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_jolokia
Executable file
|
@ -0,0 +1,523 @@
|
|||
#!/usr/bin/python
|
||||
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
import urllib2, sys, os, socket, base64, ssl
|
||||
from httplib import HTTPConnection, HTTPSConnection
|
||||
|
||||
try:
|
||||
from simplejson import json
|
||||
except ImportError:
|
||||
try:
|
||||
import json
|
||||
except ImportError:
|
||||
sys.stdout.write("<<<jolokia_info>>>\n")
|
||||
sys.stdout.write("Error: Missing JSON library for Agent Plugin mk_jolokia\n")
|
||||
exit()
|
||||
|
||||
opt_verbose = '--verbose' in sys.argv
|
||||
opt_debug = '--debug' in sys.argv
|
||||
|
||||
class PreemptiveBasicAuthHandler(urllib2.HTTPBasicAuthHandler):
|
||||
"""
|
||||
sends basic authentication with the first request,
|
||||
before the server even asks for it
|
||||
"""
|
||||
|
||||
def http_request(self, req):
|
||||
url = req.get_full_url()
|
||||
realm = None
|
||||
user, pw = self.passwd.find_user_password(realm, url)
|
||||
if pw:
|
||||
raw = "%s:%s" % (user, pw)
|
||||
auth = 'Basic %s' % base64.b64encode(raw).strip()
|
||||
req.add_unredirected_header(self.auth_header, auth)
|
||||
return req
|
||||
|
||||
https_request = http_request
|
||||
|
||||
class HTTPSValidatingConnection(HTTPSConnection):
|
||||
def __init__(self, host, ca_file, key_file, cert_file):
|
||||
HTTPSConnection.__init__(self, host, key_file=key_file, cert_file=cert_file)
|
||||
self.__ca_file = ca_file
|
||||
self.__key_file = key_file
|
||||
self.__cert_file = cert_file
|
||||
|
||||
def connect(self):
|
||||
HTTPConnection.connect(self)
|
||||
if self.__ca_file:
|
||||
self.sock = ssl.wrap_socket(self.sock, keyfile=self.key_file, certfile=self.cert_file,
|
||||
ca_certs=self.__ca_file, cert_reqs=ssl.CERT_REQUIRED)
|
||||
else:
|
||||
self.sock = ssl.wrap_socket(self.sock, keyfile=self.key_file, certfile=self.cert_file,
|
||||
ca_certs=self.__ca_file, cert_reqs=ssl.CERT_NONE)
|
||||
|
||||
|
||||
class HTTPSAuthHandler(urllib2.HTTPSHandler):
|
||||
def __init__(self, ca_file, key, cert):
|
||||
urllib2.HTTPSHandler.__init__(self)
|
||||
self.__ca_file = ca_file
|
||||
self.__key = key
|
||||
self.__cert = cert
|
||||
|
||||
def https_open(self, req):
|
||||
# do_open expects a class as the first parameter but getConnection will act
|
||||
# as a facotry function
|
||||
return self.do_open(self.getConnection, req)
|
||||
|
||||
def getConnection(self, host, timeout):
|
||||
return HTTPSValidatingConnection(host, ca_file=self.__ca_file,
|
||||
key_file=self.__key, cert_file=self.__cert)
|
||||
|
||||
def fetch_url_get(base_url, path, function):
|
||||
if path:
|
||||
url = "%s/%s/%s" % (base_url, function, path)
|
||||
else:
|
||||
url = base_url + "/"
|
||||
|
||||
if opt_verbose:
|
||||
sys.stderr.write("DEBUG: Fetching: %s\n" % url)
|
||||
try:
|
||||
json_data = urllib2.urlopen(url).read()
|
||||
if opt_verbose:
|
||||
sys.stderr.write("DEBUG: Result: %s\n\n" % json_data)
|
||||
except Exception, e:
|
||||
if opt_debug:
|
||||
raise
|
||||
sys.stderr.write("ERROR: %s\n" % e)
|
||||
return []
|
||||
return json_data
|
||||
|
||||
|
||||
def fetch_url_post(base_url, path, service_url, service_user, service_password, function):
|
||||
segments = path.split("/")
|
||||
|
||||
data = {
|
||||
"type": function.upper(),
|
||||
"mbean": segments[0],
|
||||
"attribute": segments[1],
|
||||
"target": {
|
||||
"url": service_url,
|
||||
},
|
||||
}
|
||||
if len(segments) > 2:
|
||||
data["path"] = segments[2]
|
||||
|
||||
if service_user:
|
||||
data["target"]["user"] = service_user
|
||||
data["target"]["password"] = service_password
|
||||
|
||||
if opt_verbose:
|
||||
sys.stderr.write("DEBUG: Fetching: %s\n" % base_url)
|
||||
try:
|
||||
json_data = urllib2.urlopen(base_url, data=json.dumps(data)).read()
|
||||
if opt_verbose:
|
||||
sys.stderr.write("DEBUG: Result: %s\n\n" % json_data)
|
||||
except Exception, e:
|
||||
if opt_debug:
|
||||
raise
|
||||
sys.stderr.write("ERROR: %s\n" % e)
|
||||
return []
|
||||
return json_data
|
||||
|
||||
def fetch_var(protocol, server, port, path, suburi, itemspec, service_url, service_user,
|
||||
service_password, function="read"):
|
||||
base_url = "%s://%s:%d/%s" % (protocol, server, port, suburi)
|
||||
|
||||
if service_url is not None:
|
||||
json_data = fetch_url_post(base_url, path,
|
||||
service_url, service_user, service_password, function)
|
||||
else:
|
||||
json_data = fetch_url_get(base_url, path, function)
|
||||
|
||||
try:
|
||||
obj = json.loads(json_data)
|
||||
except Exception, e:
|
||||
sys.stderr.write('ERROR: Invalid json code (%s)\n' % e)
|
||||
sys.stderr.write(' Response %s\n' % json_data)
|
||||
return []
|
||||
|
||||
if obj.get('status', 200) != 200:
|
||||
sys.stderr.write('ERROR: Invalid response when fetching url %s\n' % base_url)
|
||||
sys.stderr.write(' Response: %s\n' % json_data)
|
||||
return []
|
||||
|
||||
# Only take the value of the object. If the value is an object
|
||||
# take the first items first value.
|
||||
# {'Catalina:host=localhost,path=\\/test,type=Manager': {'activeSessions': 0}}
|
||||
if 'value' not in obj:
|
||||
if opt_verbose:
|
||||
sys.stderr.write("ERROR: not found: %s\n" % path)
|
||||
return []
|
||||
val = obj.get('value', None)
|
||||
return make_item_list((), val, itemspec)
|
||||
|
||||
# convert single values into lists of items in
|
||||
# case value is a 1-levelled or 2-levelled dict
|
||||
def make_item_list(path, value, itemspec):
|
||||
if type(value) != dict:
|
||||
if type(value) == str:
|
||||
value = value.replace(r'\/', '/')
|
||||
return [(path, value)]
|
||||
else:
|
||||
result = []
|
||||
for key, subvalue in value.items():
|
||||
# Handle filtering via itemspec
|
||||
miss = False
|
||||
while itemspec and '=' in itemspec[0]:
|
||||
if itemspec[0] not in key:
|
||||
miss = True
|
||||
break
|
||||
itemspec = itemspec[1:]
|
||||
if miss:
|
||||
continue
|
||||
item = extract_item(key, itemspec)
|
||||
if not item:
|
||||
item = (key,)
|
||||
result += make_item_list(path + item, subvalue, [])
|
||||
return result
|
||||
|
||||
# Example:
|
||||
# key = 'Catalina:host=localhost,path=\\/,type=Manager'
|
||||
# itemsepc = [ "path" ]
|
||||
# --> "/"
|
||||
|
||||
def extract_item(key, itemspec):
|
||||
path = key.split(":", 1)[-1]
|
||||
components = path.split(",")
|
||||
item = ()
|
||||
comp_dict = {}
|
||||
for comp in components:
|
||||
parts = comp.split("=")
|
||||
if len(parts) == 2:
|
||||
left, right = parts
|
||||
comp_dict[left] = right
|
||||
for pathkey in itemspec:
|
||||
if pathkey in comp_dict:
|
||||
right = comp_dict[pathkey]
|
||||
right = right.replace(r'\/', '/')
|
||||
if '/' in right:
|
||||
right = '/' + right.split('/')[-1]
|
||||
item = item + (right,)
|
||||
return item
|
||||
|
||||
|
||||
def fetch_metric(inst, path, title, itemspec, inst_add=None):
|
||||
values = fetch_var(inst["protocol"], inst["server"], inst["port"], path,
|
||||
inst["suburi"], itemspec,
|
||||
inst["service_url"], inst["service_user"], inst["service_password"])
|
||||
|
||||
for subinstance, value in values:
|
||||
if not subinstance and not title:
|
||||
sys.stdout.write("INTERNAL ERROR: %s\n" % value)
|
||||
continue
|
||||
|
||||
if "threadStatus" in subinstance or "threadParam" in subinstance:
|
||||
continue
|
||||
|
||||
if len(subinstance) > 1:
|
||||
item = ",".join((inst["instance"],) + subinstance[:-1])
|
||||
elif inst_add is not None:
|
||||
item = inst["instance"] + "," + inst_add
|
||||
else:
|
||||
item = inst["instance"]
|
||||
if title:
|
||||
if subinstance:
|
||||
tit = title + "." + subinstance[-1]
|
||||
else:
|
||||
tit = title
|
||||
else:
|
||||
tit = subinstance[-1]
|
||||
|
||||
yield (item.replace(" ", "_"), tit, value)
|
||||
|
||||
|
||||
def query_instance(inst):
|
||||
# Prepare user/password authentication via HTTP Auth
|
||||
password_mngr = urllib2.HTTPPasswordMgrWithDefaultRealm()
|
||||
if inst.get("password"):
|
||||
password_mngr.add_password(None, "%s://%s:%d/" %
|
||||
(inst["protocol"], inst["server"], inst["port"]), inst["user"], inst["password"])
|
||||
|
||||
handlers = []
|
||||
if inst["protocol"] == "https":
|
||||
if inst["mode"] == 'https' and (inst["client_key"] is None or
|
||||
inst["client_cert"] is None):
|
||||
sys.stdout.write('<<<jolokia_info>>>\n')
|
||||
sys.stderr.write("ERROR: https set up as authentication method but certificate "
|
||||
"wasn't provided\n")
|
||||
return
|
||||
handlers.append(HTTPSAuthHandler(inst["cert_path"],
|
||||
inst["client_key"], inst["client_cert"]))
|
||||
if inst["mode"] == 'digest':
|
||||
handlers.append(urllib2.HTTPDigestAuthHandler(password_mngr))
|
||||
elif inst["mode"] == "basic_preemptive":
|
||||
handlers.append(PreemptiveBasicAuthHandler(password_mngr))
|
||||
elif inst["mode"] == "basic" and inst["protocol"] != "https":
|
||||
handlers.append(urllib2.HTTPBasicAuthHandler(password_mngr))
|
||||
|
||||
if handlers:
|
||||
opener = urllib2.build_opener(*handlers)
|
||||
urllib2.install_opener(opener)
|
||||
|
||||
# Determine type of server
|
||||
server_info = fetch_var(inst["protocol"], inst["server"], inst["port"], "", inst["suburi"],
|
||||
"", None, None, None)
|
||||
|
||||
sys.stdout.write('<<<jolokia_info>>>\n')
|
||||
if server_info:
|
||||
d = dict(server_info)
|
||||
version = d.get(('info', 'version'), "unknown")
|
||||
product = d.get(('info', 'product'), "unknown")
|
||||
if inst.get("product"):
|
||||
product = inst["product"]
|
||||
agentversion = d.get(('agent',), "unknown")
|
||||
sys.stdout.write("%s %s %s %s\n" % (inst["instance"], product, version, agentversion))
|
||||
else:
|
||||
sys.stdout.write("%s ERROR\n" % (inst["instance"],))
|
||||
sys.stdout.write('<<<jolokia_metrics>>>\n')
|
||||
sys.stdout.write("%s ERROR\n" % (inst["instance"],))
|
||||
return
|
||||
|
||||
|
||||
mbean_search_results = {}
|
||||
|
||||
sys.stdout.write('<<<jolokia_metrics>>>\n')
|
||||
# Fetch the general information first
|
||||
for var in global_vars + specific_vars.get(product, []):
|
||||
# support old and new configuration format so we stay compatible with older
|
||||
# configuration files
|
||||
if len(var) == 3:
|
||||
path, title, itemspec = var
|
||||
mbean, path = path.split("/", 1)
|
||||
do_search = False
|
||||
else:
|
||||
mbean, path, title, itemspec, do_search = var
|
||||
|
||||
queries = []
|
||||
if do_search:
|
||||
if mbean in mbean_search_results:
|
||||
paths = mbean_search_results[mbean]
|
||||
else:
|
||||
paths = fetch_var(inst["protocol"], inst["server"], inst["port"], mbean,
|
||||
inst["suburi"], "", None, None, None, function="search")[0][1]
|
||||
mbean_search_results[mbean] = paths
|
||||
|
||||
for mbean_exp in paths:
|
||||
queries.append( (inst, "%s/%s" % (urllib2.quote(mbean_exp), path), path,
|
||||
itemspec, mbean_exp) )
|
||||
else:
|
||||
queries.append( (inst, mbean + "/" + path, title, itemspec) )
|
||||
|
||||
for inst, mbean_path, title, itemspec in queries:
|
||||
try:
|
||||
for out_item, out_title, out_value in fetch_metric(inst, mbean_path, title, itemspec):
|
||||
sys.stdout.write("%s %s %s\n" % (out_item, out_title, out_value) )
|
||||
except IOError:
|
||||
return
|
||||
except socket.timeout:
|
||||
return
|
||||
except:
|
||||
if opt_debug:
|
||||
raise
|
||||
# Simply ignore exceptions. Need to be removed for debugging
|
||||
continue
|
||||
|
||||
if custom_vars:
|
||||
sys.stdout.write('<<<jolokia_generic>>>\n')
|
||||
for var in custom_vars:
|
||||
mbean, path, title, itemspec, do_search, value_type = var
|
||||
queries = []
|
||||
if do_search:
|
||||
if mbean in mbean_search_results:
|
||||
paths = mbean_search_results[mbean]
|
||||
else:
|
||||
paths = fetch_var(inst["protocol"], inst["server"], inst["port"], mbean,
|
||||
inst["suburi"], "", None, None, None, function="search")[0][1]
|
||||
mbean_search_results[mbean] = paths
|
||||
|
||||
for mbean_exp in paths:
|
||||
queries.append( (inst, "%s/%s" % (urllib2.quote(mbean_exp), path), path,
|
||||
itemspec, mbean_exp) )
|
||||
else:
|
||||
queries.append( (inst, mbean + "/" + path, title, itemspec) )
|
||||
|
||||
for inst, mbean_path, title, itemspec in queries:
|
||||
try:
|
||||
for out_item, out_title, out_value in fetch_metric(inst, mbean_path, title, itemspec):
|
||||
sys.stdout.write("%s %s %s %s\n" % (out_item, out_title, out_value, value_type) )
|
||||
except IOError:
|
||||
return
|
||||
except socket.timeout:
|
||||
return
|
||||
except:
|
||||
if opt_debug:
|
||||
raise
|
||||
# Simply ignore exceptions. Need to be removed for debugging
|
||||
continue
|
||||
|
||||
|
||||
# Default configuration for all instances
|
||||
protocol = "http"
|
||||
server = "localhost"
|
||||
port = 8080
|
||||
user = "monitoring"
|
||||
password = None
|
||||
mode = "digest"
|
||||
suburi = "jolokia"
|
||||
instance = None
|
||||
cert_path = "_default"
|
||||
client_cert = None
|
||||
client_key = None
|
||||
service_url = None
|
||||
service_user = None
|
||||
service_password = None
|
||||
product = None
|
||||
|
||||
global_vars = [
|
||||
( "java.lang:type=Memory", "NonHeapMemoryUsage/used", "NonHeapMemoryUsage", [], False),
|
||||
( "java.lang:type=Memory", "NonHeapMemoryUsage/max", "NonHeapMemoryMax", [], False),
|
||||
( "java.lang:type=Memory", "HeapMemoryUsage/used", "HeapMemoryUsage", [], False),
|
||||
( "java.lang:type=Memory", "HeapMemoryUsage/max", "HeapMemoryMax", [], False),
|
||||
( "java.lang:type=Threading", "ThreadCount", "ThreadCount", [], False),
|
||||
( "java.lang:type=Threading", "DaemonThreadCount", "DeamonThreadCount", [], False),
|
||||
( "java.lang:type=Threading", "PeakThreadCount", "PeakThreadCount", [], False),
|
||||
( "java.lang:type=Threading", "TotalStartedThreadCount", "TotalStartedThreadCount", [], False),
|
||||
( "java.lang:type=Runtime", "Uptime", "Uptime", [], False),
|
||||
( "java.lang:type=GarbageCollector,name=*", "CollectionCount", "", [], False),
|
||||
( "java.lang:type=GarbageCollector,name=*", "CollectionTime", "", [], False),
|
||||
( "java.lang:name=CMS%20Perm%20Gen,type=MemoryPool", "Usage/used", "PermGenUsage", [], False),
|
||||
( "java.lang:name=CMS%20Perm%20Gen,type=MemoryPool", "Usage/max", "PermGenMax", [], False),
|
||||
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "OffHeapHits", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "OnDiskHits", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "InMemoryHitPercentage", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "CacheMisses", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "OnDiskHitPercentage", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "MemoryStoreObjectCount", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "DiskStoreObjectCount", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "CacheMissPercentage", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "CacheHitPercentage", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "OffHeapHitPercentage", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "InMemoryMisses", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "OffHeapStoreObjectCount", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "WriterQueueLength", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "WriterMaxQueueSize", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "OffHeapMisses", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "InMemoryHits", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "AssociatedCacheName", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "ObjectCount", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "OnDiskMisses", "", [], True),
|
||||
( "net.sf.ehcache:CacheManager=CacheManagerApplication*,*,type=CacheStatistics", "CacheHits", "", [], True),
|
||||
]
|
||||
|
||||
|
||||
specific_vars = {
|
||||
"weblogic" : [
|
||||
( "*:*", "CompletedRequestCount", None, [ "ServerRuntime" ] , False),
|
||||
( "*:*", "QueueLength", None, [ "ServerRuntime" ] , False),
|
||||
( "*:*", "StandbyThreadCount", None, [ "ServerRuntime" ] , False),
|
||||
( "*:*", "PendingUserRequestCount", None, [ "ServerRuntime" ] , False),
|
||||
( "*:Name=ThreadPoolRuntime,*", "ExecuteThreadTotalCount", None, [ "ServerRuntime" ] , False),
|
||||
( "*:*", "ExecuteThreadIdleCount", None, [ "ServerRuntime" ] , False),
|
||||
( "*:*", "HoggingThreadCount", None, [ "ServerRuntime" ] , False),
|
||||
( "*:Type=WebAppComponentRuntime,*", "OpenSessionsCurrentCount", None, [ "ServerRuntime", "ApplicationRuntime" ] , False),
|
||||
],
|
||||
"tomcat" : [
|
||||
( "*:type=Manager,*", "activeSessions,maxActiveSessions", None, [ "path", "context" ] , False),
|
||||
( "*:j2eeType=Servlet,name=default,*", "stateName", None, [ "WebModule" ] , False),
|
||||
# Check not yet working
|
||||
( "*:j2eeType=Servlet,name=default,*", "requestCount", None, [ "WebModule" ], False),
|
||||
( "*:name=*,type=ThreadPool", "maxThreads", None, [], False),
|
||||
( "*:name=*,type=ThreadPool", "currentThreadCount", None, [], False),
|
||||
( "*:name=*,type=ThreadPool", "currentThreadsBusy", None, [], False),
|
||||
# too wide location for addressing the right info
|
||||
# ( "*:j2eeType=Servlet,*", "requestCount", None, [ "WebModule" ] , False),
|
||||
],
|
||||
"jboss" : [
|
||||
( "*:type=Manager,*", "activeSessions,maxActiveSessions", None, [ "path", "context" ] , False),
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
# ( '*:j2eeType=WebModule,name=/--/localhost/-/%(app)s,*/state', None, [ "name" ]),
|
||||
# ( '*:j2eeType=Servlet,WebModule=/--/localhost/-/%(app)s,name=%(servlet)s,*/requestCount', None, [ "WebModule", "name" ]),
|
||||
# ( "Catalina:J2EEApplication=none,J2EEServer=none,WebModule=*,j2eeType=Servlet,name=*", None, [ "WebModule", "name" ]),
|
||||
|
||||
|
||||
# List of instances to monitor. Each instance is a dict where
|
||||
# the global configuration values can be overridden.
|
||||
instances = [{}]
|
||||
|
||||
custom_vars = []
|
||||
|
||||
conffile = os.getenv("MK_CONFDIR", "/etc/check_mk") + "/jolokia.cfg"
|
||||
|
||||
if os.path.exists(conffile):
|
||||
execfile(conffile)
|
||||
|
||||
if server == "use fqdn":
|
||||
server = socket.getfqdn()
|
||||
|
||||
if instance == None:
|
||||
instance = str(port)
|
||||
|
||||
# We have to deal with socket timeouts. Python > 2.6
|
||||
# supports timeout parameter for the urllib2.urlopen method
|
||||
# but we are on a python 2.5 system here which seem to use the
|
||||
# default socket timeout. We are local here so set it to 1 second.
|
||||
socket.setdefaulttimeout(1.0)
|
||||
|
||||
# Compute list of instances to monitor. If the user has defined
|
||||
# instances in his configuration, we will use this (a list
|
||||
# of dicts).
|
||||
for inst in instances:
|
||||
for varname, value in [
|
||||
("protocol", protocol),
|
||||
("server", server),
|
||||
("port", port),
|
||||
("user", user),
|
||||
("password", password),
|
||||
("mode", mode),
|
||||
("suburi", suburi),
|
||||
("instance", instance),
|
||||
("cert_path", cert_path),
|
||||
("client_cert", client_cert),
|
||||
("client_key", client_key),
|
||||
("service_url", service_url),
|
||||
("service_user", service_user),
|
||||
("service_password", service_password),
|
||||
( "product", product ),
|
||||
]:
|
||||
if varname not in inst:
|
||||
inst[varname] = value
|
||||
if not inst["instance"]:
|
||||
inst["instance"] = str(inst["port"])
|
||||
inst["instance"] = inst["instance"].replace(" ", "_")
|
||||
|
||||
if inst.get("server") == "use fqdn":
|
||||
inst["server"] = socket.getfqdn()
|
||||
|
||||
query_instance(inst)
|
29
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_logins
Executable file
29
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_logins
Executable file
|
@ -0,0 +1,29 @@
|
|||
#!/bin/bash
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
if type who >/dev/null; then
|
||||
echo "<<<logins>>>"
|
||||
who | wc -l
|
||||
fi
|
564
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_logwatch
Executable file
564
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_logwatch
Executable file
|
@ -0,0 +1,564 @@
|
|||
#!/usr/bin/python
|
||||
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# Call with -d for debug mode: colored output, no saving of status
|
||||
|
||||
import sys, os, re, time, glob
|
||||
|
||||
|
||||
# .--MEI-Cleanup---------------------------------------------------------.
|
||||
# | __ __ _____ ___ ____ _ |
|
||||
# | | \/ | ____|_ _| / ___| | ___ __ _ _ __ _ _ _ __ |
|
||||
# | | |\/| | _| | |_____| | | |/ _ \/ _` | '_ \| | | | '_ \ |
|
||||
# | | | | | |___ | |_____| |___| | __/ (_| | | | | |_| | |_) | |
|
||||
# | |_| |_|_____|___| \____|_|\___|\__,_|_| |_|\__,_| .__/ |
|
||||
# | |_| |
|
||||
# +----------------------------------------------------------------------+
|
||||
# In case the program crashes or is killed in a hard way, the frozen binary .exe
|
||||
# may leave temporary directories named "_MEI..." in the temporary path. Clean them
|
||||
# up to prevent eating disk space over time.
|
||||
|
||||
########################################################################
|
||||
############## DUPLICATE CODE WARNING ##################################
|
||||
### This code is also used in the cmk-update-agent frozen binary #######
|
||||
### Any changes to this class should also be made in cmk-update-agent ##
|
||||
### In the bright future we will move this code into a library #########
|
||||
########################################################################
|
||||
|
||||
class MEIFolderCleaner(object):
|
||||
def pid_running(self, pid):
|
||||
import ctypes
|
||||
kernel32 = ctypes.windll.kernel32
|
||||
SYNCHRONIZE = 0x100000
|
||||
|
||||
process = kernel32.OpenProcess(SYNCHRONIZE, 0, pid)
|
||||
|
||||
if process != 0:
|
||||
kernel32.CloseHandle(process)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def find_and_remove_leftover_folders(self, hint_filenames):
|
||||
if not hasattr(sys, "frozen"):
|
||||
return
|
||||
|
||||
import win32file # pylint: disable=import-error
|
||||
import tempfile
|
||||
base_path = tempfile.gettempdir()
|
||||
for f in os.listdir(base_path):
|
||||
try:
|
||||
path = os.path.join(base_path, f)
|
||||
|
||||
if not os.path.isdir(path):
|
||||
continue
|
||||
|
||||
# Only care about directories related to our program
|
||||
invalid_dir = False
|
||||
for hint_filename in hint_filenames:
|
||||
if not os.path.exists(os.path.join(path, hint_filename)):
|
||||
invalid_dir = True
|
||||
break
|
||||
if invalid_dir:
|
||||
continue
|
||||
|
||||
pyinstaller_tmp_path = win32file.GetLongPathName(sys._MEIPASS).lower() # pylint: disable=no-member
|
||||
if pyinstaller_tmp_path == path.lower():
|
||||
continue # Skip our own directory
|
||||
|
||||
# Extract the process id from the directory and check whether or not it is still
|
||||
# running. Don't delete directories of running processes!
|
||||
# The name of the temporary directories is "_MEI<PID><NR>". We try to extract the PID
|
||||
# by stripping of a single digit from the right. In the hope the NR is a single digit
|
||||
# in all relevant cases.
|
||||
pid = int(f[4:-1])
|
||||
if self.pid_running(pid):
|
||||
continue
|
||||
|
||||
shutil.rmtree(path)
|
||||
except Exception, e:
|
||||
# TODO: introduce verbose mode for mk_logwatch
|
||||
pass
|
||||
#.
|
||||
|
||||
os_type = "linux"
|
||||
try:
|
||||
import platform
|
||||
os_type = platform.system().lower()
|
||||
except:
|
||||
pass
|
||||
|
||||
if '-d' in sys.argv[1:] or '--debug' in sys.argv[1:]:
|
||||
tty_red = '\033[1;31m'
|
||||
tty_green = '\033[1;32m'
|
||||
tty_yellow = '\033[1;33m'
|
||||
tty_blue = '\033[1;34m'
|
||||
tty_normal = '\033[0m'
|
||||
debug = True
|
||||
else:
|
||||
tty_red = ''
|
||||
tty_green = ''
|
||||
tty_yellow = ''
|
||||
tty_blue = ''
|
||||
tty_normal = ''
|
||||
debug = False
|
||||
|
||||
# The configuration file and status file are searched
|
||||
# in the directory named by the environment variable
|
||||
# LOGWATCH_DIR. If that is not set, MK_CONFDIR is used.
|
||||
# If that is not set either, the current directory ist
|
||||
# used.
|
||||
logwatch_dir = os.getenv("LOGWATCH_DIR")
|
||||
if logwatch_dir:
|
||||
mk_confdir = logwatch_dir
|
||||
mk_vardir = logwatch_dir
|
||||
else:
|
||||
mk_confdir = os.getenv("MK_CONFDIR") or "."
|
||||
mk_vardir = os.getenv("MK_VARDIR") or os.getenv("MK_STATEDIR") or "."
|
||||
|
||||
|
||||
sys.stdout.write("<<<logwatch>>>\n")
|
||||
|
||||
config_filename = mk_confdir + "/logwatch.cfg"
|
||||
config_dir = mk_confdir + "/logwatch.d/*.cfg"
|
||||
|
||||
|
||||
# Determine the name of the state file
|
||||
# $REMOTE set -> logwatch.state.$REMOTE
|
||||
# $REMOTE not set and a tty -> logwatch.state.local
|
||||
# $REMOTE not set and not a tty -> logwatch.state
|
||||
remote_hostname = os.getenv("REMOTE", "")
|
||||
remote_hostname = remote_hostname.replace(":", "_")
|
||||
if remote_hostname != "":
|
||||
status_filename = "%s/logwatch.state.%s" % (mk_vardir, remote_hostname)
|
||||
else:
|
||||
if sys.stdout.isatty():
|
||||
status_filename = "%s/logwatch.state.local" % mk_vardir
|
||||
else:
|
||||
status_filename = "%s/logwatch.state" % mk_vardir
|
||||
|
||||
# Copy the last known state from the logwatch.state when there is no status_filename yet.
|
||||
if not os.path.exists(status_filename) and os.path.exists("%s/logwatch.state" % mk_vardir):
|
||||
import shutil
|
||||
shutil.copy("%s/logwatch.state" % mk_vardir, status_filename)
|
||||
|
||||
def is_not_comment(line):
|
||||
if line.lstrip().startswith('#') or \
|
||||
line.strip() == '':
|
||||
return False
|
||||
return True
|
||||
|
||||
def parse_filenames(line):
|
||||
return line.split()
|
||||
|
||||
def parse_pattern(level, pattern, line):
|
||||
if level not in [ 'C', 'W', 'I', 'O' ]:
|
||||
raise Exception("Invalid pattern line '%s'" % line)
|
||||
|
||||
try:
|
||||
compiled = re.compile(pattern)
|
||||
except:
|
||||
raise Exception("Invalid regular expression in line '%s'" % line)
|
||||
|
||||
return (level, compiled)
|
||||
|
||||
def read_config():
|
||||
config_lines = []
|
||||
try:
|
||||
config_lines += [ line.rstrip() for line in filter(is_not_comment, file(config_filename).readlines()) ]
|
||||
except IOError, e:
|
||||
if debug:
|
||||
raise
|
||||
|
||||
# Add config from a logwatch.d folder
|
||||
for config_file in glob.glob(config_dir):
|
||||
config_lines += [ line.rstrip() for line in filter(is_not_comment, file(config_file).readlines()) ]
|
||||
|
||||
have_filenames = False
|
||||
config = []
|
||||
cont_list = []
|
||||
rewrite_list = []
|
||||
|
||||
for line in config_lines:
|
||||
if line[0].isspace(): # pattern line
|
||||
if not have_filenames:
|
||||
raise Exception("Missing logfile names")
|
||||
|
||||
level, pattern = line.split(None, 1)
|
||||
|
||||
if level == 'A':
|
||||
cont_list.append(parse_cont_pattern(pattern))
|
||||
elif level == 'R':
|
||||
rewrite_list.append(pattern)
|
||||
else:
|
||||
level, compiled = parse_pattern(level, pattern, line)
|
||||
# New pattern for line matching => clear continuation and rewrite patterns
|
||||
cont_list = []
|
||||
rewrite_list = []
|
||||
# TODO: Fix the code and remove the pragma below!
|
||||
patterns.append((level, compiled, cont_list, rewrite_list)) # pylint: disable=used-before-assignment
|
||||
|
||||
else: # filename line
|
||||
patterns = []
|
||||
cont_list = [] # Clear list of continuation patterns from last file
|
||||
rewrite_list = [] # Same for rewrite patterns
|
||||
config.append((parse_filenames(line), patterns))
|
||||
have_filenames = True
|
||||
return config
|
||||
|
||||
def parse_cont_pattern(pattern):
|
||||
try:
|
||||
return int(pattern)
|
||||
except:
|
||||
try:
|
||||
return re.compile(pattern)
|
||||
except:
|
||||
if debug:
|
||||
raise
|
||||
raise Exception("Invalid regular expression in line '%s'" % pattern)
|
||||
|
||||
# structure of statusfile
|
||||
# # LOGFILE OFFSET INODE
|
||||
# /var/log/messages|7767698|32455445
|
||||
# /var/test/x12134.log|12345|32444355
|
||||
def read_status():
|
||||
if debug:
|
||||
return {}
|
||||
|
||||
status = {}
|
||||
for line in file(status_filename):
|
||||
# TODO: Remove variants with spaces. rsplit is
|
||||
# not portable. split fails if logfilename contains
|
||||
# spaces
|
||||
inode = -1
|
||||
try:
|
||||
parts = line.split('|')
|
||||
filename = parts[0]
|
||||
offset = parts[1]
|
||||
if len(parts) >= 3:
|
||||
inode = parts[2]
|
||||
|
||||
except:
|
||||
try:
|
||||
filename, offset = line.rsplit(None, 1)
|
||||
except:
|
||||
filename, offset = line.split(None, 1)
|
||||
status[filename] = int(offset), int(inode)
|
||||
return status
|
||||
|
||||
def save_status(status):
|
||||
f = file(status_filename, "w")
|
||||
for filename, (offset, inode) in status.items():
|
||||
f.write("%s|%d|%d\n" % (filename, offset, inode))
|
||||
|
||||
pushed_back_line = None
|
||||
def next_line(file_handle):
|
||||
global pushed_back_line
|
||||
if pushed_back_line != None:
|
||||
line = pushed_back_line
|
||||
pushed_back_line = None
|
||||
return line
|
||||
else:
|
||||
try:
|
||||
line = file_handle.next()
|
||||
# Avoid parsing of (yet) incomplete lines (when acutal application
|
||||
# is just in the process of writing)
|
||||
# Just check if the line ends with a \n. This handles \n and \r\n
|
||||
if not line.endswith("\n"):
|
||||
begin_of_line_offset = file_handle.tell() - len(line)
|
||||
os.lseek(file_handle.fileno(), begin_of_line_offset, 0)
|
||||
return None
|
||||
return line
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def is_inode_cabable(path):
|
||||
if "linux" in os_type:
|
||||
return True
|
||||
elif "windows" in os_type:
|
||||
volume_name = "%s:\\\\" % path.split(":", 1)[0]
|
||||
import win32api # pylint: disable=import-error
|
||||
volume_info = win32api.GetVolumeInformation(volume_name)
|
||||
volume_type = volume_info[-1]
|
||||
if "ntfs" in volume_type.lower():
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def process_logfile(logfile, patterns):
|
||||
global pushed_back_line
|
||||
|
||||
# Look at which file offset we have finished scanning
|
||||
# the logfile last time. If we have never seen this file
|
||||
# before, we set the offset to -1
|
||||
offset, prev_inode = status.get(logfile, (-1, -1))
|
||||
try:
|
||||
file_desc = os.open(logfile, os.O_RDONLY)
|
||||
if not is_inode_cabable(logfile):
|
||||
inode = 1 # Create a dummy inode
|
||||
else:
|
||||
inode = os.fstat(file_desc)[1] # 1 = st_ino
|
||||
except:
|
||||
if debug:
|
||||
raise
|
||||
sys.stdout.write("[[[%s:cannotopen]]]\n" % logfile)
|
||||
return
|
||||
|
||||
sys.stdout.write("[[[%s]]]\n" % logfile)
|
||||
|
||||
# Seek to the current end in order to determine file size
|
||||
current_end = os.lseek(file_desc, 0, 2) # os.SEEK_END not available in Python 2.4
|
||||
status[logfile] = current_end, inode
|
||||
|
||||
# If we have never seen this file before, we just set the
|
||||
# current pointer to the file end. We do not want to make
|
||||
# a fuss about ancient log messages...
|
||||
if offset == -1:
|
||||
if not debug:
|
||||
return
|
||||
else:
|
||||
offset = 0
|
||||
|
||||
|
||||
# If the inode of the logfile has changed it has appearently
|
||||
# been started from new (logfile rotation). At least we must
|
||||
# assume that. In some rare cases (restore of a backup, etc)
|
||||
# we are wrong and resend old log messages
|
||||
if prev_inode >= 0 and inode != prev_inode:
|
||||
offset = 0
|
||||
|
||||
# Our previously stored offset is the current end ->
|
||||
# no new lines in this file
|
||||
if offset == current_end:
|
||||
return # nothing new
|
||||
|
||||
# If our offset is beyond the current end, the logfile has been
|
||||
# truncated or wrapped while keeping the same inode. We assume
|
||||
# that it contains all new data in that case and restart from
|
||||
# offset 0.
|
||||
if offset > current_end:
|
||||
offset = 0
|
||||
|
||||
# now seek to offset where interesting data begins
|
||||
os.lseek(file_desc, offset, 0) # os.SEEK_SET not available in Python 2.4
|
||||
if os_type == "windows":
|
||||
import io # Available with python 2.6
|
||||
import codecs
|
||||
# Some windows files are encoded in utf_16
|
||||
# Peak the first two bytes to determine the encoding...
|
||||
peak_handle = os.fdopen(file_desc, "rb")
|
||||
first_two_bytes = peak_handle.read(2)
|
||||
use_encoding = None
|
||||
if first_two_bytes == "\xFF\xFE":
|
||||
use_encoding = "utf_16"
|
||||
elif first_two_bytes == "\xFE\xFF":
|
||||
use_encoding = "utf_16_be"
|
||||
|
||||
os.lseek(file_desc, offset, 0) # os.SEEK_SET not available in Python 2.4
|
||||
file_handle = io.open(file_desc, encoding = use_encoding)
|
||||
else:
|
||||
file_handle = os.fdopen(file_desc)
|
||||
worst = -1
|
||||
outputtxt = ""
|
||||
lines_parsed = 0
|
||||
start_time = time.time()
|
||||
|
||||
while True:
|
||||
line = next_line(file_handle)
|
||||
if line == None:
|
||||
break # End of file
|
||||
|
||||
# Handle option maxlinesize
|
||||
if opt_maxlinesize != None and len(line) > opt_maxlinesize:
|
||||
line = line[:opt_maxlinesize] + "[TRUNCATED]\n"
|
||||
|
||||
lines_parsed += 1
|
||||
# Check if maximum number of new log messages is exceeded
|
||||
if opt_maxlines != None and lines_parsed > opt_maxlines:
|
||||
outputtxt += "%s Maximum number (%d) of new log messages exceeded.\n" % (
|
||||
opt_overflow, opt_maxlines)
|
||||
worst = max(worst, opt_overflow_level)
|
||||
os.lseek(file_desc, 0, 2) # Seek to end of file, skip all other messages
|
||||
break
|
||||
|
||||
# Check if maximum processing time (per file) is exceeded. Check only
|
||||
# every 100'th line in order to save system calls
|
||||
if opt_maxtime != None and lines_parsed % 100 == 10 \
|
||||
and time.time() - start_time > opt_maxtime:
|
||||
outputtxt += "%s Maximum parsing time (%.1f sec) of this log file exceeded.\n" % (
|
||||
opt_overflow, opt_maxtime)
|
||||
worst = max(worst, opt_overflow_level)
|
||||
os.lseek(file_desc, 0, 2) # Seek to end of file, skip all other messages
|
||||
break
|
||||
|
||||
level = "."
|
||||
for lev, pattern, cont_patterns, replacements in patterns:
|
||||
matches = pattern.search(line[:-1])
|
||||
if matches:
|
||||
level = lev
|
||||
levelint = {'C': 2, 'W': 1, 'O': 0, 'I': -1, '.': -1}[lev]
|
||||
worst = max(levelint, worst)
|
||||
|
||||
# Check for continuation lines
|
||||
for cont_pattern in cont_patterns:
|
||||
if type(cont_pattern) == int: # add that many lines
|
||||
for _unused_x in range(cont_pattern):
|
||||
cont_line = next_line(file_handle)
|
||||
if cont_line == None: # end of file
|
||||
break
|
||||
line = line[:-1] + "\1" + cont_line
|
||||
|
||||
else: # pattern is regex
|
||||
while True:
|
||||
cont_line = next_line(file_handle)
|
||||
if cont_line == None: # end of file
|
||||
break
|
||||
elif cont_pattern.search(cont_line[:-1]):
|
||||
line = line[:-1] + "\1" + cont_line
|
||||
else:
|
||||
pushed_back_line = cont_line # sorry for stealing this line
|
||||
break
|
||||
|
||||
# Replacement
|
||||
for replace in replacements:
|
||||
line = replace.replace('\\0', line.rstrip()) + "\n"
|
||||
for nr, group in enumerate(matches.groups()):
|
||||
line = line.replace('\\%d' % (nr+1), group)
|
||||
|
||||
break # matching rule found and executed
|
||||
|
||||
color = {'C': tty_red, 'W': tty_yellow, 'O': tty_green, 'I': tty_blue, '.': ''}[level]
|
||||
if debug:
|
||||
line = line.replace("\1", "\nCONT:")
|
||||
if level == "I":
|
||||
level = "."
|
||||
if opt_nocontext and level == '.':
|
||||
continue
|
||||
outputtxt += "%s%s %s%s\n" % (color, level, line[:-1], tty_normal)
|
||||
|
||||
new_offset = os.lseek(file_desc, 0, 1) # os.SEEK_CUR not available in Python 2.4
|
||||
status[logfile] = new_offset, inode
|
||||
|
||||
# output all lines if at least one warning, error or ok has been found
|
||||
if worst > -1:
|
||||
sys.stdout.write(outputtxt)
|
||||
sys.stdout.flush()
|
||||
|
||||
# Handle option maxfilesize, regardless of warning or errors that have happened
|
||||
if opt_maxfilesize != None and (offset / opt_maxfilesize) < (new_offset / opt_maxfilesize):
|
||||
sys.stdout.write("%sW Maximum allowed logfile size (%d bytes) exceeded for the %dth time.%s\n" %
|
||||
(tty_yellow, opt_maxfilesize, new_offset / opt_maxfilesize, tty_normal))
|
||||
|
||||
try:
|
||||
# This removes leftover folders which may be generated by crashing frozen binaries
|
||||
folder_cleaner = MEIFolderCleaner()
|
||||
folder_cleaner.find_and_remove_leftover_folders(hint_filenames = ["mk_logwatch.exe.manifest"])
|
||||
except Exception, e:
|
||||
sys.stdout.write("ERROR WHILE DOING FOLDER: %s\n" % e)
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
config = read_config()
|
||||
except Exception, e:
|
||||
if debug:
|
||||
raise
|
||||
sys.stdout.write("CANNOT READ CONFIG FILE: %s\n" % e)
|
||||
sys.exit(1)
|
||||
|
||||
# Simply ignore errors in the status file. In case of a corrupted status file we simply begin
|
||||
# with an empty status. That keeps the monitoring up and running - even if we might lose a
|
||||
# message in the extreme case of a corrupted status file.
|
||||
try:
|
||||
status = read_status()
|
||||
except Exception, e:
|
||||
status = {}
|
||||
|
||||
|
||||
logfile_patterns = {}
|
||||
# The filename line may contain options like 'maxlines=100' or 'maxtime=10'
|
||||
for filenames, patterns in config:
|
||||
# Initialize options with default values
|
||||
opt_maxlines = None
|
||||
opt_maxtime = None
|
||||
opt_maxlinesize = None
|
||||
opt_maxfilesize = None
|
||||
opt_regex = None
|
||||
opt_overflow = 'C'
|
||||
opt_overflow_level = 2
|
||||
opt_nocontext = False
|
||||
try:
|
||||
options = [ o.split('=', 1) for o in filenames if '=' in o ]
|
||||
for key, value in options:
|
||||
if key == 'maxlines':
|
||||
opt_maxlines = int(value)
|
||||
elif key == 'maxtime':
|
||||
opt_maxtime = float(value)
|
||||
elif key == 'maxlinesize':
|
||||
opt_maxlinesize = int(value)
|
||||
elif key == 'maxfilesize':
|
||||
opt_maxfilesize = int(value)
|
||||
elif key == 'overflow':
|
||||
if value not in [ 'C', 'I', 'W', 'O' ]:
|
||||
raise Exception("Invalid value %s for overflow. Allowed are C, I, O and W" % value)
|
||||
opt_overflow = value
|
||||
opt_overflow_level = {'C':2, 'W':1, 'O':0, 'I':0}[value]
|
||||
elif key == 'regex':
|
||||
opt_regex = re.compile(value)
|
||||
elif key == 'iregex':
|
||||
opt_regex = re.compile(value, re.I)
|
||||
elif key == 'nocontext':
|
||||
opt_nocontext = True
|
||||
else:
|
||||
raise Exception("Invalid option %s" % key)
|
||||
except Exception, e:
|
||||
if debug:
|
||||
raise
|
||||
sys.stdout.write("INVALID CONFIGURATION: %s\n" % e)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
for glob_pattern in filenames:
|
||||
if '=' in glob_pattern:
|
||||
continue
|
||||
logfiles = glob.glob(glob_pattern)
|
||||
if opt_regex:
|
||||
logfiles = [ f for f in logfiles if opt_regex.search(f) ]
|
||||
if len(logfiles) == 0:
|
||||
sys.stdout.write('[[[%s:missing]]]\n' % glob_pattern)
|
||||
else:
|
||||
for logfile in logfiles:
|
||||
logfile_patterns[logfile] = logfile_patterns.get(logfile, []) + patterns
|
||||
|
||||
for logfile, patterns in logfile_patterns.items():
|
||||
process_logfile(logfile, patterns)
|
||||
|
||||
if not debug:
|
||||
save_status(status)
|
13
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_logwatch.aix
Executable file
13
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_logwatch.aix
Executable file
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/ksh
|
||||
# Logfile monitoring for AIX via errpt
|
||||
# Beware: This Plugin clears the errors after each run,
|
||||
# but it creates an detailed backup in /var/log/errpt_TIMESTAMP.log
|
||||
|
||||
echo "<<<logwatch>>>"
|
||||
echo "[[[errorlog]]]"
|
||||
OUT=$(errpt | awk 'NR>1 { printf "C %s\n", $0 }')
|
||||
if [[ $OUT != '' ]];then
|
||||
echo "$OUT"
|
||||
errpt -a > /var/log/errpt_$(date +%s).log
|
||||
errclear 0
|
||||
fi
|
205
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_mongodb
Executable file
205
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_mongodb
Executable file
|
@ -0,0 +1,205 @@
|
|||
#!/usr/bin/python
|
||||
# Monitor MongoDB on Linux
|
||||
|
||||
import sys
|
||||
import time
|
||||
import pprint
|
||||
import os
|
||||
import datetime
|
||||
|
||||
# This agent plugin creates various sections out of the MongoDB server status information.
|
||||
# Important: 1) If MongoDB runs as single instance the agent data is assigned
|
||||
# to the host same host where the plugin resides.
|
||||
#
|
||||
# 2) If MongoDB is deployed as replica set the agent data is piggybacked
|
||||
# to a different hostname, name after the replica set name.
|
||||
# You have to create a new host in the monitoring system matching the
|
||||
# replica set name, or use the piggyback translation rule to modify the
|
||||
# hostname according to your needs.
|
||||
|
||||
try:
|
||||
import pymongo
|
||||
except ImportError, e:
|
||||
sys.stderr.write("ERROR: Unable to import pymongo module\n")
|
||||
sys.exit(2)
|
||||
|
||||
# TODO: might be implemented in the future..
|
||||
host = None
|
||||
port = None
|
||||
|
||||
try:
|
||||
con = pymongo.MongoClient(host, port)
|
||||
try:
|
||||
# pylint: disable=no-member
|
||||
con = pymongo.database_names()
|
||||
except:
|
||||
con = pymongo.MongoClient(None, None, read_preference=pymongo.ReadPreference.SECONDARY)
|
||||
|
||||
con.admin.read_preference = pymongo.ReadPreference.SECONDARY
|
||||
|
||||
# if user and passwd:
|
||||
# db = con["admin"]
|
||||
# if not db.authenticate(user, passwd):
|
||||
# sys.exit("Username/Password incorrect")
|
||||
|
||||
server_status = con.admin.command("serverStatus")
|
||||
except:
|
||||
sys.stdout.write("<<<mongodb_instance:sep(9)>>>\n")
|
||||
sys.stdout.write("error\tInstance is down\n")
|
||||
sys.exit(0)
|
||||
|
||||
server_version = tuple(con.server_info()['version'].split('.'))
|
||||
|
||||
repl_info = server_status.get("repl")
|
||||
|
||||
sys.stdout.write("<<<mongodb_instance:sep(9)>>>\n")
|
||||
if not repl_info:
|
||||
sys.stdout.write("mode\tSingle Instance\n")
|
||||
else:
|
||||
if repl_info.get("ismaster"):
|
||||
sys.stdout.write("mode\tPrimary\n")
|
||||
elif repl_info.get("secondary"):
|
||||
sys.stdout.write("mode\tSecondary\n")
|
||||
else:
|
||||
sys.stdout.write("mode\tArbiter\n")
|
||||
sys.stdout.write("address\t%s\n" % repl_info["me"])
|
||||
|
||||
sys.stdout.write("version\t%s\n" % server_status["version"])
|
||||
sys.stdout.write("pid\t%s\n" % server_status["pid"])
|
||||
|
||||
if repl_info:
|
||||
if not repl_info.get("ismaster"):
|
||||
sys.exit(0)
|
||||
sys.stdout.write("<<<<%s>>>>\n" % repl_info["setName"])
|
||||
sys.stdout.write("<<<mongodb_replica:sep(9)>>>\n")
|
||||
sys.stdout.write("primary\t%s\n" % repl_info.get("primary"))
|
||||
sys.stdout.write("hosts\t%s\n" % " ".join(repl_info.get("hosts")))
|
||||
sys.stdout.write("arbiters\t%s\n" % " ".join(repl_info.get("arbiters")))
|
||||
|
||||
sys.stdout.write("<<<mongodb_replstatus>>>\n")
|
||||
sys.stdout.write(pprint.pformat(con.admin.command("replSetGetStatus")))
|
||||
|
||||
sys.stdout.write("<<<mongodb_asserts>>>\n")
|
||||
for key, value in server_status.get("asserts", {}).items():
|
||||
sys.stdout.write("%s %s\n" % (key, value))
|
||||
|
||||
|
||||
sys.stdout.write("<<<mongodb_connections>>>\n")
|
||||
sys.stdout.write("%s\n" % "\n".join(map(lambda x: "%s %s" % x, server_status["connections"].items())))
|
||||
|
||||
databases = dict(map(lambda x: (x, {}), con.database_names()))
|
||||
|
||||
for name in databases.keys():
|
||||
databases[name]["collections"] = con[name].collection_names()
|
||||
databases[name]["stats"] = con[name].command("dbstats")
|
||||
databases[name]["collstats"] = {}
|
||||
for collection in databases[name]["collections"]:
|
||||
databases[name]["collstats"][collection] = con[name].command("collstats", collection)
|
||||
|
||||
|
||||
sys.stdout.write("<<<mongodb_chunks>>>\n")
|
||||
col = con.config.chunks
|
||||
for db_name, db_data in databases.items():
|
||||
shards = col.distinct("shard")
|
||||
sys.stdout.write("shardcount %d\n" % len(shards))
|
||||
for collection in db_data.get("collections"):
|
||||
nsfilter = "%s.%s" % (db_name, collection)
|
||||
sys.stdout.write("nscount %s %s\n" % (nsfilter, col.find({"ns": nsfilter}).count()))
|
||||
for shard in shards:
|
||||
sys.stdout.write("shardmatches %s#%s %s\n" % (nsfilter, shard, col.find({"ns": nsfilter, "shard": shard}).count()))
|
||||
|
||||
sys.stdout.write("<<<mongodb_locks>>>\n")
|
||||
global_lock_info = server_status.get("globalLock")
|
||||
if global_lock_info:
|
||||
for what in [ "activeClients", "currentQueue" ]:
|
||||
if what in global_lock_info:
|
||||
for key, value in global_lock_info[what].items():
|
||||
sys.stdout.write("%s %s %s\n" % (what, key, value))
|
||||
|
||||
sys.stdout.write("<<<mongodb_flushing>>>\n")
|
||||
sys.stdout.write("average_ms %s\n" % server_status["backgroundFlushing"]["average_ms"])
|
||||
sys.stdout.write("last_ms %s\n" % server_status["backgroundFlushing"]["last_ms"])
|
||||
sys.stdout.write("flushed %s\n" % server_status["backgroundFlushing"]["flushes"])
|
||||
|
||||
# Unused
|
||||
#try:
|
||||
# if server_version >= tuple("2.4.0".split(".")):
|
||||
# indexCounters = server_status['indexCounters']
|
||||
# else:
|
||||
# indexCounters = server_status['indexCounters']["btree"]
|
||||
# print "<<<mongodb_indexcounters>>>"
|
||||
# for key, value in indexCounters.items():
|
||||
# print "%s %s" % (key, value)
|
||||
#except:
|
||||
# pass
|
||||
|
||||
sys.stdout.write("<<<mongodb_mem>>>\n")
|
||||
for key, value in server_status["mem"].items():
|
||||
sys.stdout.write("%s %s\n" % (key, value))
|
||||
for key, value in server_status["extra_info"].items():
|
||||
sys.stdout.write("%s %s\n" % (key, value))
|
||||
|
||||
sys.stdout.write("<<<mongodb_counters>>>\n")
|
||||
for what in ["opcounters", "opcountersRepl"]:
|
||||
for key, value in server_status.get(what, {}).items():
|
||||
sys.stdout.write("%s %s %s\n" % (what, key, value))
|
||||
|
||||
sys.stdout.write("<<<mongodb_collections:sep(9)>>>\n")
|
||||
for dbname, dbdata in databases.items():
|
||||
for collname, colldata in dbdata.get("collstats", {}).items():
|
||||
for what, value in colldata.items():
|
||||
sys.stdout.write("%s\t%s\t%s\t%s\n" % (dbname, collname, what, value))
|
||||
|
||||
sys.stdout.write("<<<logwatch>>>\n")
|
||||
sys.stdout.write("[[[MongoDB startupWarnings]]]\n")
|
||||
startup_warnings = con.admin.command({"getLog": "startupWarnings"})
|
||||
|
||||
var_dir = os.environ.get("MK_VARDIR")
|
||||
if var_dir:
|
||||
state_file = "%s/mongodb.state" % var_dir
|
||||
last_timestamp = None
|
||||
output_all = False
|
||||
|
||||
# Supports: Nov 6 13:44:09
|
||||
# 2015-10-17T05:35:24
|
||||
def get_timestamp(text):
|
||||
for pattern in [ "%a %b %d %H:%M:%S",
|
||||
"%Y-%m-%dT%H:%M:%S" ]:
|
||||
try:
|
||||
result = time.mktime(time.strptime(text, pattern))
|
||||
return result
|
||||
except:
|
||||
continue
|
||||
|
||||
year_available = False
|
||||
if os.path.exists(state_file):
|
||||
last_timestamp = int(file(state_file).read())
|
||||
if time.localtime(last_timestamp).tm_year >= 2015:
|
||||
year_available = True
|
||||
|
||||
# Note: there is no year information in these loglines
|
||||
# As workaround we look at the creation date (year) of the last statefile
|
||||
# If it differs and there are new messages we start from the beginning
|
||||
if not year_available:
|
||||
statefile_year = time.localtime(os.stat(state_file).st_ctime).tm_year
|
||||
if time.localtime().tm_year != statefile_year:
|
||||
output_all = True
|
||||
|
||||
for line in startup_warnings["log"]:
|
||||
state = "C"
|
||||
state_index = line.find("]")+2
|
||||
if len(line) == state_index or line[state_index:].startswith("** "):
|
||||
state = "."
|
||||
|
||||
if "** WARNING:" in line:
|
||||
state = "W"
|
||||
|
||||
if output_all or get_timestamp(line.split(".")[0]) > last_timestamp:
|
||||
sys.stdout.write("%s %s\n" % (state, line))
|
||||
|
||||
# update state file
|
||||
if startup_warnings["log"]:
|
||||
file(state_file, "w").write("%d" % get_timestamp(startup_warnings["log"][-1].split(".")[0]))
|
||||
|
||||
sys.stdout.write("<<<<>>>>\n")
|
||||
|
92
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_mysql
Executable file
92
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_mysql
Executable file
|
@ -0,0 +1,92 @@
|
|||
#!/bin/bash
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# gets optional socket as argument
|
||||
function do_query() {
|
||||
INSTANCE=$(echo $1|awk -v FS="=" '{print $2}')
|
||||
COUNT=$(ps -efww | grep [/]usr/sbin/mysqld | grep socket | wc -l)
|
||||
if [ $COUNT -gt 1 ]
|
||||
then
|
||||
INSTANCE_NAME=$(ps -efww|grep socket|grep "${INSTANCE}"|grep "[u]ser" | sed -ne 's/.*socket=\([^.]*\).*/\1/p')
|
||||
INSTANCE_NAME="[[${INSTANCE_NAME##*/}]]"
|
||||
else
|
||||
INSTANCE_NAME="[[$(ps -efww|grep socket|grep "${INSTANCE}"|grep "[u]ser" | sed -ne 's/.*user=\([^ ]*\).*/\1/p')]]"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Check if mysqld is running and root password setup
|
||||
echo "<<<mysql_ping>>>"
|
||||
echo $INSTANCE_NAME
|
||||
mysqladmin --defaults-extra-file=$MK_CONFDIR/mysql.cfg $1 ping 2>&1
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
|
||||
echo "<<<mysql>>>"
|
||||
echo $INSTANCE_NAME
|
||||
mysql --defaults-extra-file=$MK_CONFDIR/mysql.cfg $1 -sN \
|
||||
-e "show global status ; show global variables ;"
|
||||
|
||||
echo "<<<mysql_capacity>>>"
|
||||
echo $INSTANCE_NAME
|
||||
mysql --defaults-extra-file=$MK_CONFDIR/mysql.cfg $1 -sN \
|
||||
-e "SELECT table_schema, sum(data_length + index_length), sum(data_free)
|
||||
FROM information_schema.TABLES GROUP BY table_schema"
|
||||
|
||||
echo "<<<mysql_slave>>>"
|
||||
echo $INSTANCE_NAME
|
||||
mysql --defaults-extra-file=$MK_CONFDIR/mysql.cfg $1 -s \
|
||||
-e "show slave status\G"
|
||||
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
if which mysqladmin >/dev/null
|
||||
then
|
||||
mysql_sockets=$(fgrep socket $MK_CONFDIR/mysql.cfg|sed -ne 's/.*socket=\([^ ]*\).*/\1/p')
|
||||
if [ -z "$mysql_sockets" ] ; then
|
||||
mysql_sockets=$(ps -efww | grep mysqld | grep "[s]ocket" | sed -ne 's/.*socket=\([^ ]*\).*/\1/p')
|
||||
fi
|
||||
if [ -z "$mysql_sockets" ] ; then
|
||||
do_query ""
|
||||
else
|
||||
for socket in $mysql_sockets ; do
|
||||
do_query "--socket="$socket
|
||||
done
|
||||
fi
|
||||
#echo "<<<mysql_version>>>"
|
||||
#mysql -V
|
||||
|
||||
echo "<<<mysql_port>>>"
|
||||
ps -efww|grep mysqld|while read LINE; do echo $LINE|grep "[u]ser" | sed -ne 's/.*user=\([^ ]*\).*/\1/p'; echo $LINE|grep mysqld | grep "[p]ort"|sed -ne 's/.*port=\([^ ]*\).*/\1/p' ; done|xargs -n2
|
||||
|
||||
#echo "<<<mysql_instances>>>"
|
||||
#mysql --defaults-extra-file=$MK_CONFDIR/mysql.cfg $1 -s \
|
||||
# -e "show INSTANCES"
|
||||
|
||||
fi
|
||||
|
||||
|
30
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_omreport
Executable file
30
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_omreport
Executable file
|
@ -0,0 +1,30 @@
|
|||
#!/bin/bash
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
if which omreport >/dev/null
|
||||
then
|
||||
echo "<<<dell_om_vdisks>>>"
|
||||
omreport storage vdisk
|
||||
fi
|
1378
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_oracle
Executable file
1378
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_oracle
Executable file
File diff suppressed because it is too large
Load Diff
1152
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_oracle.aix
Executable file
1152
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_oracle.aix
Executable file
File diff suppressed because it is too large
Load Diff
38
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_oracle_asm
Executable file
38
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_oracle_asm
Executable file
|
@ -0,0 +1,38 @@
|
|||
#!/bin/bash
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# Check_MK agent plugin for monitoring ORACLE ASM
|
||||
|
||||
if [ ! -e $MK_CONFDIR/asmcmd.sh ]; then
|
||||
echo "$MK_CONFDIR/asmcmd.sh does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
function asmcmd () {
|
||||
$MK_CONFDIR/asmcmd.sh "$@"
|
||||
}
|
||||
|
||||
echo "<<<oracle_asm_diskgroup>>>"
|
||||
asmcmd lsdg | grep -v State | grep -v "The Oracle"
|
127
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_oracle_crs
Executable file
127
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_oracle_crs
Executable file
|
@ -0,0 +1,127 @@
|
|||
#!/bin/bash
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# Developed by Thorsten Bruhns from OPITZ CONSULTING Deutschland GmbH
|
||||
|
||||
set -f
|
||||
|
||||
ocrcfgfile=/etc/oracle/ocr.loc
|
||||
olrcfgfile=/etc/oracle/olr.loc
|
||||
resourcefilter="^NAME=|^TYPE=|^STATE=|^TARGET=|^ENABLED="
|
||||
|
||||
# .--Functions-----------------------------------------------------------.
|
||||
# | _____ _ _ |
|
||||
# | | ___| _ _ __ ___| |_(_) ___ _ __ ___ |
|
||||
# | | |_ | | | | '_ \ / __| __| |/ _ \| '_ \/ __| |
|
||||
# | | _|| |_| | | | | (__| |_| | (_) | | | \__ \ |
|
||||
# | |_| \__,_|_| |_|\___|\__|_|\___/|_| |_|___/ |
|
||||
# | |
|
||||
# +----------------------------------------------------------------------+
|
||||
# | |
|
||||
# '----------------------------------------------------------------------'
|
||||
|
||||
function set_has_env(){
|
||||
test -f ${ocrcfgfile} || exit 0
|
||||
local_has_type=$(cat $ocrcfgfile | grep "^local_only=" | cut -d"=" -f2 | tr '[:lower:]' '[:upper:]')
|
||||
local_has_type=${local_has_type:-"FALSE"}
|
||||
|
||||
if [ -f ${olrcfgfile} ] ; then
|
||||
has_ORACLE_HOME=$(cat $olrcfgfile | grep "^crs_home=" | cut -d"=" -f2)
|
||||
else
|
||||
# There is no olr.cfg in 10.2 and 11.1
|
||||
# we try to get the ORA_CRS_HOME from /etc/init.d/init.cssd
|
||||
local_has_type=FALSE
|
||||
INITCSSD=/etc/init.d/init.cssd
|
||||
if [ ! -f ${INITCSSD} ] ; then
|
||||
exit 0
|
||||
else
|
||||
has_ORACLE_HOME=$(grep "^ORA_CRS_HOME=" ${INITCSSD} | cut -d"=" -f2-)
|
||||
fi
|
||||
fi
|
||||
|
||||
CRSCTL=${has_ORACLE_HOME}/bin/crsctl
|
||||
OLSNODES=${has_ORACLE_HOME}/bin/olsnodes
|
||||
CRS_STAT=${has_ORACLE_HOME}/bin/crs_stat
|
||||
}
|
||||
|
||||
function printhasdata() {
|
||||
ps -e | grep cssd.bin > /dev/null || exit 0
|
||||
|
||||
echo "<<<oracle_crs_version:sep(124)>>>"
|
||||
$CRSCTL query has releaseversion
|
||||
|
||||
echo "<<<oracle_crs_res>>>"
|
||||
$CRSCTL stat res -f | grep -E $resourcefilter
|
||||
}
|
||||
|
||||
function printcrsdata() {
|
||||
ps -e | grep -e ohasd.bin -e crsd.bin > /dev/null || exit 0
|
||||
|
||||
echo "<<<oracle_crs_version:sep(124)>>>"
|
||||
crs_version=$($CRSCTL query crs releaseversion)
|
||||
echo $crs_version
|
||||
|
||||
echo "<<<oracle_crs_voting>>>"
|
||||
$CRSCTL query css votedisk | grep "^ [0-9]"
|
||||
|
||||
ps -e | grep crsd.bin > /dev/null || exit 0
|
||||
echo "<<<oracle_crs_res:sep(124)>>>"
|
||||
OLS_NODENAME=$($OLSNODES -l)
|
||||
|
||||
echo "nodename|"$OLS_NODENAME
|
||||
|
||||
crs_version_short=$(echo $crs_version | cut -d"[" -f2- | cut -d"." -f-2 | sed 's/\.//')
|
||||
if [ $(($crs_version_short)) -ge 112 ] ; then
|
||||
$CRSCTL stat res -v -n $OLS_NODENAME -init | grep -E $resourcefilter | sed "s/^/csslocal\|/"
|
||||
for nodelist in $($OLSNODES)
|
||||
do
|
||||
$CRSCTL stat res -v -n $nodelist | grep -E $resourcefilter | sed "s/^/$nodelist\|/"
|
||||
done
|
||||
else
|
||||
$CRS_STAT -f -c $OLS_NODENAME | grep -E $resourcefilter | sed "s/^/$OLS_NODENAME\|/"
|
||||
fi
|
||||
}
|
||||
|
||||
# .--Main----------------------------------------------------------------.
|
||||
# | __ __ _ |
|
||||
# | | \/ | __ _(_)_ __ |
|
||||
# | | |\/| |/ _` | | '_ \ |
|
||||
# | | | | | (_| | | | | | |
|
||||
# | |_| |_|\__,_|_|_| |_| |
|
||||
# | |
|
||||
# +----------------------------------------------------------------------+
|
||||
# | |
|
||||
# '----------------------------------------------------------------------'
|
||||
|
||||
set_has_env
|
||||
echo "<<<oracle_crs_res>>>"
|
||||
echo "<<<oracle_crs_version>>>"
|
||||
echo "<<<oracle_crs_votedisk>>>"
|
||||
if [ $local_has_type = 'FALSE' ] ; then
|
||||
printcrsdata
|
||||
else
|
||||
printhasdata
|
||||
fi
|
||||
|
485
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_postgres
Executable file
485
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_postgres
Executable file
|
@ -0,0 +1,485 @@
|
|||
#!/bin/bash
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2015 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
|
||||
# TODO postgres_connections output format
|
||||
|
||||
|
||||
# .--common funcs--------------------------------------------------------.
|
||||
# | __ |
|
||||
# | ___ ___ _ __ ___ _ __ ___ ___ _ __ / _|_ _ _ __ ___ ___ |
|
||||
# | / __/ _ \| '_ ` _ \| '_ ` _ \ / _ \| '_ \ | |_| | | | '_ \ / __/ __| |
|
||||
# || (_| (_) | | | | | | | | | | | (_) | | | || _| |_| | | | | (__\__ \ |
|
||||
# | \___\___/|_| |_| |_|_| |_| |_|\___/|_| |_||_| \__,_|_| |_|\___|___/ |
|
||||
# | |
|
||||
# '----------------------------------------------------------------------'
|
||||
|
||||
|
||||
function compare_version_greater_equal() {
|
||||
local GREATER_ONE
|
||||
GREATER_ONE=$(echo "$1 $2" | awk '{if ($1 >= $2) print $1; else print $2}')
|
||||
if [ "$GREATER_ONE" == "$1" ] ; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
#.
|
||||
# .--section funcs-------------------------------------------------------.
|
||||
# | _ _ __ |
|
||||
# | ___ ___ ___| |_(_) ___ _ __ / _|_ _ _ __ ___ ___ |
|
||||
# | / __|/ _ \/ __| __| |/ _ \| '_ \ | |_| | | | '_ \ / __/ __| |
|
||||
# | \__ \ __/ (__| |_| | (_) | | | | | _| |_| | | | | (__\__ \ |
|
||||
# | |___/\___|\___|\__|_|\___/|_| |_| |_| \__,_|_| |_|\___|___/ |
|
||||
# | |
|
||||
# '----------------------------------------------------------------------'
|
||||
|
||||
|
||||
function postgres_instances() {
|
||||
echo '<<<postgres_instances>>>'
|
||||
# If we have no instances we take db id (pqsql/postgres) because
|
||||
# ps output may be unreadable
|
||||
# In case of instances ps output shows them readable
|
||||
if [ ! -z "${1}" ]; then
|
||||
echo "[[[${1}]]]"
|
||||
fi
|
||||
pgrep -laf bin/postgres
|
||||
}
|
||||
|
||||
|
||||
function postgres_sessions() {
|
||||
# Postgres 9.2 uses 'query' instead of 'current_query'
|
||||
local OUTPUT
|
||||
OUTPUT="$(echo "\echo '<<<postgres_sessions>>>${INSTANCE_SECTION}'
|
||||
SELECT (
|
||||
SELECT column_name
|
||||
FROM information_schema.columns
|
||||
WHERE table_name='pg_stat_activity' AND column_name in ('query', 'current_query')
|
||||
) = '<IDLE>' as query, count(*)
|
||||
FROM pg_stat_activity
|
||||
GROUP BY (query = '<IDLE>');" |\
|
||||
su - "$DBUSER" -c "$export_PGPASSFILE $psql -X --variable ON_ERROR_STOP=1 -d $PGDATABASE ${EXTRA_ARGS} -A -t -F' '" 2>/dev/null)"
|
||||
|
||||
echo "$OUTPUT"
|
||||
# line with number of idle sessions is sometimes missing on Postgres 8.x. This can lead
|
||||
# to an altogether empty section and thus the check disappearing.
|
||||
echo "$OUTPUT" | grep -q '^t ' || echo "t 0"
|
||||
}
|
||||
|
||||
|
||||
function postgres_simple_queries() {
|
||||
# Querytime
|
||||
# Supports versions >= 8.3, > 9.1
|
||||
local QUERYTIME_QUERY
|
||||
if compare_version_greater_equal "$POSTGRES_VERSION" "9.2" ; then
|
||||
QUERYTIME_QUERY="SELECT datname, datid, usename, client_addr, state AS state, COALESCE(ROUND(EXTRACT(epoch FROM now()-query_start)),0) AS seconds,
|
||||
pid, regexp_replace(query, E'[\\n\\r\\u2028]+', ' ', 'g' ) AS current_query FROM pg_stat_activity WHERE (query_start IS NOT NULL AND (state NOT LIKE 'idle%' OR state IS NULL)) ORDER BY query_start, pid DESC;"
|
||||
else
|
||||
QUERYTIME_QUERY="SELECT datname, datid, usename, client_addr, '' AS state, COALESCE(ROUND(EXTRACT(epoch FROM now()-query_start)),0) AS seconds,
|
||||
procpid as pid, regexp_replace(current_query, E'[\\n\\r\\u2028]+', ' ', 'g' ) AS current_query FROM pg_stat_activity WHERE (query_start IS NOT NULL AND current_query NOT LIKE '<IDLE>%') ORDER BY query_start, procpid DESC;"
|
||||
fi
|
||||
|
||||
# Number of current connections per database
|
||||
# We need to output the databases, too.
|
||||
# This query does not report databases without an active query
|
||||
local CONNECTIONS_QUERY
|
||||
if compare_version_greater_equal "$POSTGRES_VERSION" "9.2" ; then
|
||||
CONNECTIONS_QUERY="SELECT COUNT(datid) AS current,
|
||||
(SELECT setting AS mc FROM pg_settings WHERE name = 'max_connections') AS mc,
|
||||
d.datname
|
||||
FROM pg_database d
|
||||
LEFT JOIN pg_stat_activity s ON (s.datid = d.oid) WHERE state <> 'idle'
|
||||
GROUP BY 2,3
|
||||
ORDER BY datname;"
|
||||
else
|
||||
CONNECTIONS_QUERY="SELECT COUNT(datid) AS current,
|
||||
(SELECT setting AS mc FROM pg_settings WHERE name = 'max_connections') AS mc,
|
||||
d.datname
|
||||
FROM pg_database d
|
||||
LEFT JOIN pg_stat_activity s ON (s.datid = d.oid) WHERE current_query <> '<IDLE>'
|
||||
GROUP BY 2,3
|
||||
ORDER BY datname;"
|
||||
fi
|
||||
|
||||
echo "\pset footer off
|
||||
\echo '<<<postgres_stat_database:sep(59)>>>${INSTANCE_SECTION}'
|
||||
SELECT datid, datname, numbackends, xact_commit, xact_rollback, blks_read, blks_hit, tup_returned, tup_fetched, tup_inserted, tup_updated, tup_deleted, pg_database_size(datname) AS datsize FROM pg_stat_database;
|
||||
|
||||
\echo '<<<postgres_locks:sep(59)>>>${INSTANCE_SECTION}'
|
||||
\echo '[databases_start]'
|
||||
$ECHO_DATABASES
|
||||
\echo '[databases_end]'
|
||||
SELECT datname, granted, mode FROM pg_locks l RIGHT JOIN pg_database d ON (d.oid=l.database) WHERE d.datallowconn;
|
||||
|
||||
\echo '<<<postgres_query_duration:sep(59)>>>${INSTANCE_SECTION}'
|
||||
\echo '[databases_start]'
|
||||
$ECHO_DATABASES
|
||||
\echo '[databases_end]'
|
||||
$QUERYTIME_QUERY
|
||||
|
||||
\echo '<<<postgres_connections:sep(59)>>>${INSTANCE_SECTION}'
|
||||
\echo '[databases_start]'
|
||||
$ECHO_DATABASES
|
||||
\echo '[databases_end]'
|
||||
$CONNECTIONS_QUERY" \
|
||||
| su - "$DBUSER" -c "$export_PGPASSFILE $psql -X -d $PGDATABASE ${EXTRA_ARGS} -q -A -F';'"
|
||||
}
|
||||
|
||||
|
||||
function postgres_stats() {
|
||||
# Contains last vacuum time and analyze time
|
||||
local LASTVACUUM="SELECT current_database() AS datname, nspname AS sname, relname AS tname,
|
||||
CASE WHEN v IS NULL THEN -1 ELSE round(extract(epoch FROM v)) END AS vtime,
|
||||
CASE WHEN g IS NULL THEN -1 ELSE round(extract(epoch FROM v)) END AS atime
|
||||
FROM (SELECT nspname, relname, GREATEST(pg_stat_get_last_vacuum_time(c.oid), pg_stat_get_last_autovacuum_time(c.oid)) AS v,
|
||||
GREATEST(pg_stat_get_last_analyze_time(c.oid), pg_stat_get_last_autoanalyze_time(c.oid)) AS g
|
||||
FROM pg_class c, pg_namespace n
|
||||
WHERE relkind = 'r' AND n.oid = c.relnamespace AND n.nspname <> 'information_schema'
|
||||
ORDER BY 3) AS foo;"
|
||||
|
||||
local FIRST=
|
||||
local QUERY="\pset footer off
|
||||
BEGIN;
|
||||
SET statement_timeout=30000;
|
||||
COMMIT;
|
||||
|
||||
\echo '<<<postgres_stats:sep(59)>>>${INSTANCE_SECTION}'
|
||||
\echo '[databases_start]'
|
||||
$ECHO_DATABASES
|
||||
\echo '[databases_end]'"
|
||||
|
||||
for db in $DATABASES ; do
|
||||
QUERY="$QUERY
|
||||
\c $db
|
||||
$LASTVACUUM
|
||||
"
|
||||
if [ -z $FIRST ] ; then
|
||||
FIRST=false
|
||||
QUERY="$QUERY
|
||||
\pset tuples_only on
|
||||
"
|
||||
fi
|
||||
done
|
||||
echo "$QUERY" | su - "$DBUSER" -c "$export_PGPASSFILE $psql -X ${EXTRA_ARGS} -q -A -F';'" | grep -v -e 'COMMIT$' -e 'SET$' -e 'BEGIN$'
|
||||
}
|
||||
|
||||
|
||||
function postgres_version() {
|
||||
# Postgres version an connection time
|
||||
echo -e "<<<postgres_version:sep(1)>>>${INSTANCE_SECTION}"
|
||||
(TIMEFORMAT='%3R'; time echo "SELECT version() AS v" |\
|
||||
su - "$DBUSER" -c "$export_PGPASSFILE $psql -X -d $PGDATABASE ${EXTRA_ARGS} -t -A -F';'; echo -e '<<<postgres_conn_time>>>${INSTANCE_SECTION}'") 2>&1
|
||||
}
|
||||
|
||||
|
||||
function postgres_bloat() {
|
||||
# Bloat index and tables
|
||||
# Supports versions <9.0, >=9.0
|
||||
# This huge query has been gratefully taken from Greg Sabino Mullane's check_postgres.pl
|
||||
local BLOAT_QUERY
|
||||
if compare_version_greater_equal "$POSTGRES_VERSION" "9.0" ; then
|
||||
BLOAT_QUERY="SELECT
|
||||
current_database() AS db, schemaname, tablename, reltuples::bigint AS tups, relpages::bigint AS pages, otta,
|
||||
ROUND(CASE WHEN otta=0 OR sml.relpages=0 OR sml.relpages=otta THEN 0.0 ELSE sml.relpages/otta::numeric END,1) AS tbloat,
|
||||
CASE WHEN relpages < otta THEN 0 ELSE relpages::bigint - otta END AS wastedpages,
|
||||
CASE WHEN relpages < otta THEN 0 ELSE bs*(sml.relpages-otta)::bigint END AS wastedbytes,
|
||||
CASE WHEN relpages < otta THEN 0 ELSE (bs*(relpages-otta))::bigint END AS wastedsize,
|
||||
iname, ituples::bigint AS itups, ipages::bigint AS ipages, iotta,
|
||||
ROUND(CASE WHEN iotta=0 OR ipages=0 OR ipages=iotta THEN 0.0 ELSE ipages/iotta::numeric END,1) AS ibloat,
|
||||
CASE WHEN ipages < iotta THEN 0 ELSE ipages::bigint - iotta END AS wastedipages,
|
||||
CASE WHEN ipages < iotta THEN 0 ELSE bs*(ipages-iotta) END AS wastedibytes,
|
||||
CASE WHEN ipages < iotta THEN 0 ELSE (bs*(ipages-iotta))::bigint END AS wastedisize,
|
||||
CASE WHEN relpages < otta THEN
|
||||
CASE WHEN ipages < iotta THEN 0 ELSE bs*(ipages-iotta::bigint) END
|
||||
ELSE CASE WHEN ipages < iotta THEN bs*(relpages-otta::bigint)
|
||||
ELSE bs*(relpages-otta::bigint + ipages-iotta::bigint) END
|
||||
END AS totalwastedbytes
|
||||
FROM (
|
||||
SELECT
|
||||
nn.nspname AS schemaname,
|
||||
cc.relname AS tablename,
|
||||
COALESCE(cc.reltuples,0) AS reltuples,
|
||||
COALESCE(cc.relpages,0) AS relpages,
|
||||
COALESCE(bs,0) AS bs,
|
||||
COALESCE(CEIL((cc.reltuples*((datahdr+ma-
|
||||
(CASE WHEN datahdr%ma=0 THEN ma ELSE datahdr%ma END))+nullhdr2+4))/(bs-20::float)),0) AS otta,
|
||||
COALESCE(c2.relname,'?') AS iname, COALESCE(c2.reltuples,0) AS ituples, COALESCE(c2.relpages,0) AS ipages,
|
||||
COALESCE(CEIL((c2.reltuples*(datahdr-12))/(bs-20::float)),0) AS iotta -- very rough approximation, assumes all cols
|
||||
FROM
|
||||
pg_class cc
|
||||
JOIN pg_namespace nn ON cc.relnamespace = nn.oid AND nn.nspname <> 'information_schema'
|
||||
LEFT JOIN
|
||||
(
|
||||
SELECT
|
||||
ma,bs,foo.nspname,foo.relname,
|
||||
(datawidth+(hdr+ma-(case when hdr%ma=0 THEN ma ELSE hdr%ma END)))::numeric AS datahdr,
|
||||
(maxfracsum*(nullhdr+ma-(case when nullhdr%ma=0 THEN ma ELSE nullhdr%ma END))) AS nullhdr2
|
||||
FROM (
|
||||
SELECT
|
||||
ns.nspname, tbl.relname, hdr, ma, bs,
|
||||
SUM((1-coalesce(null_frac,0))*coalesce(avg_width, 2048)) AS datawidth,
|
||||
MAX(coalesce(null_frac,0)) AS maxfracsum,
|
||||
hdr+(
|
||||
SELECT 1+count(*)/8
|
||||
FROM pg_stats s2
|
||||
WHERE null_frac<>0 AND s2.schemaname = ns.nspname AND s2.tablename = tbl.relname
|
||||
) AS nullhdr
|
||||
FROM pg_attribute att
|
||||
JOIN pg_class tbl ON att.attrelid = tbl.oid
|
||||
JOIN pg_namespace ns ON ns.oid = tbl.relnamespace
|
||||
LEFT JOIN pg_stats s ON s.schemaname=ns.nspname
|
||||
AND s.tablename = tbl.relname
|
||||
AND s.inherited=false
|
||||
AND s.attname=att.attname,
|
||||
(
|
||||
SELECT
|
||||
(SELECT current_setting('block_size')::numeric) AS bs,
|
||||
CASE WHEN SUBSTRING(SPLIT_PART(v, ' ', 2) FROM '#\[0-9]+.[0-9]+#\%' for '#')
|
||||
IN ('8.0','8.1','8.2') THEN 27 ELSE 23 END AS hdr,
|
||||
CASE WHEN v ~ 'mingw32' OR v ~ '64-bit' THEN 8 ELSE 4 END AS ma
|
||||
FROM (SELECT version() AS v) AS foo
|
||||
) AS constants
|
||||
WHERE att.attnum > 0 AND tbl.relkind='r'
|
||||
GROUP BY 1,2,3,4,5
|
||||
) AS foo
|
||||
) AS rs
|
||||
ON cc.relname = rs.relname AND nn.nspname = rs.nspname
|
||||
LEFT JOIN pg_index i ON indrelid = cc.oid
|
||||
LEFT JOIN pg_class c2 ON c2.oid = i.indexrelid
|
||||
) AS sml
|
||||
WHERE sml.relpages - otta > 0 OR ipages - iotta > 10 ORDER BY totalwastedbytes DESC LIMIT 10;"
|
||||
else
|
||||
BLOAT_QUERY="SELECT
|
||||
current_database() AS db, schemaname, tablename, reltuples::bigint AS tups, relpages::bigint AS pages, otta,
|
||||
ROUND(CASE WHEN otta=0 OR sml.relpages=0 OR sml.relpages=otta THEN 0.0 ELSE sml.relpages/otta::numeric END,1) AS tbloat,
|
||||
CASE WHEN relpages < otta THEN 0 ELSE relpages::bigint - otta END AS wastedpages,
|
||||
CASE WHEN relpages < otta THEN 0 ELSE bs*(sml.relpages-otta)::bigint END AS wastedbytes,
|
||||
CASE WHEN relpages < otta THEN '0 bytes'::text ELSE (bs*(relpages-otta))::bigint || ' bytes' END AS wastedsize,
|
||||
iname, ituples::bigint AS itups, ipages::bigint AS ipages, iotta,
|
||||
ROUND(CASE WHEN iotta=0 OR ipages=0 OR ipages=iotta THEN 0.0 ELSE ipages/iotta::numeric END,1) AS ibloat,
|
||||
CASE WHEN ipages < iotta THEN 0 ELSE ipages::bigint - iotta END AS wastedipages,
|
||||
CASE WHEN ipages < iotta THEN 0 ELSE bs*(ipages-iotta) END AS wastedibytes,
|
||||
CASE WHEN ipages < iotta THEN '0 bytes' ELSE (bs*(ipages-iotta))::bigint || ' bytes' END AS wastedisize,
|
||||
CASE WHEN relpages < otta THEN
|
||||
CASE WHEN ipages < iotta THEN 0 ELSE bs*(ipages-iotta::bigint) END
|
||||
ELSE CASE WHEN ipages < iotta THEN bs*(relpages-otta::bigint)
|
||||
ELSE bs*(relpages-otta::bigint + ipages-iotta::bigint) END
|
||||
END AS totalwastedbytes
|
||||
FROM (
|
||||
SELECT
|
||||
nn.nspname AS schemaname,
|
||||
cc.relname AS tablename,
|
||||
COALESCE(cc.reltuples,0) AS reltuples,
|
||||
COALESCE(cc.relpages,0) AS relpages,
|
||||
COALESCE(bs,0) AS bs,
|
||||
COALESCE(CEIL((cc.reltuples*((datahdr+ma-
|
||||
(CASE WHEN datahdr%ma=0 THEN ma ELSE datahdr%ma END))+nullhdr2+4))/(bs-20::float)),0) AS otta,
|
||||
COALESCE(c2.relname,'?') AS iname, COALESCE(c2.reltuples,0) AS ituples, COALESCE(c2.relpages,0) AS ipages,
|
||||
COALESCE(CEIL((c2.reltuples*(datahdr-12))/(bs-20::float)),0) AS iotta -- very rough approximation, assumes all cols
|
||||
FROM
|
||||
pg_class cc
|
||||
JOIN pg_namespace nn ON cc.relnamespace = nn.oid AND nn.nspname <> 'information_schema'
|
||||
LEFT JOIN
|
||||
(
|
||||
SELECT
|
||||
ma,bs,foo.nspname,foo.relname,
|
||||
(datawidth+(hdr+ma-(case when hdr%ma=0 THEN ma ELSE hdr%ma END)))::numeric AS datahdr,
|
||||
(maxfracsum*(nullhdr+ma-(case when nullhdr%ma=0 THEN ma ELSE nullhdr%ma END))) AS nullhdr2
|
||||
FROM (
|
||||
SELECT
|
||||
ns.nspname, tbl.relname, hdr, ma, bs,
|
||||
SUM((1-coalesce(null_frac,0))*coalesce(avg_width, 2048)) AS datawidth,
|
||||
MAX(coalesce(null_frac,0)) AS maxfracsum,
|
||||
hdr+(
|
||||
SELECT 1+count(*)/8
|
||||
FROM pg_stats s2
|
||||
WHERE null_frac<>0 AND s2.schemaname = ns.nspname AND s2.tablename = tbl.relname
|
||||
) AS nullhdr
|
||||
FROM pg_attribute att
|
||||
JOIN pg_class tbl ON att.attrelid = tbl.oid
|
||||
JOIN pg_namespace ns ON ns.oid = tbl.relnamespace
|
||||
LEFT JOIN pg_stats s ON s.schemaname=ns.nspname
|
||||
AND s.tablename = tbl.relname
|
||||
AND s.attname=att.attname,
|
||||
(
|
||||
SELECT
|
||||
(SELECT current_setting('block_size')::numeric) AS bs,
|
||||
CASE WHEN SUBSTRING(SPLIT_PART(v, ' ', 2) FROM '#\"[0-9]+.[0-9]+#\"%' for '#')
|
||||
IN ('8.0','8.1','8.2') THEN 27 ELSE 23 END AS hdr,
|
||||
CASE WHEN v ~ 'mingw32' OR v ~ '64-bit' THEN 8 ELSE 4 END AS ma
|
||||
FROM (SELECT version() AS v) AS foo
|
||||
) AS constants
|
||||
WHERE att.attnum > 0 AND tbl.relkind='r'
|
||||
GROUP BY 1,2,3,4,5
|
||||
) AS foo
|
||||
) AS rs
|
||||
ON cc.relname = rs.relname AND nn.nspname = rs.nspname
|
||||
LEFT JOIN pg_index i ON indrelid = cc.oid
|
||||
LEFT JOIN pg_class c2 ON c2.oid = i.indexrelid
|
||||
) AS sml
|
||||
WHERE sml.relpages - otta > 0 OR ipages - iotta > 10 ORDER BY totalwastedbytes DESC LIMIT 10;"
|
||||
fi
|
||||
|
||||
local FIRST=
|
||||
local QUERY="\pset footer off
|
||||
\echo '<<<postgres_bloat:sep(59)>>>${INSTANCE_SECTION}'
|
||||
\echo '[databases_start]'
|
||||
$ECHO_DATABASES
|
||||
\echo '[databases_end]'"
|
||||
|
||||
for db in $DATABASES ; do
|
||||
QUERY="$QUERY
|
||||
\c $db
|
||||
$BLOAT_QUERY
|
||||
"
|
||||
if [ -z $FIRST ] ; then
|
||||
FIRST=false
|
||||
QUERY="$QUERY
|
||||
\pset tuples_only on
|
||||
"
|
||||
fi
|
||||
done
|
||||
echo "$QUERY" | su - "$DBUSER" -c "$export_PGPASSFILE $psql -X ${EXTRA_ARGS} -q -A -F';'"
|
||||
}
|
||||
|
||||
|
||||
#.
|
||||
# .--main----------------------------------------------------------------.
|
||||
# | _ |
|
||||
# | _ __ ___ __ _(_)_ __ |
|
||||
# | | '_ ` _ \ / _` | | '_ \ |
|
||||
# | | | | | | | (_| | | | | | |
|
||||
# | |_| |_| |_|\__,_|_|_| |_| |
|
||||
# | |
|
||||
# '----------------------------------------------------------------------'
|
||||
|
||||
|
||||
### postgres.cfg ##
|
||||
# DBUSER=OS_USER_NAME
|
||||
# INSTANCE=/home/postgres/db1.env:USER_NAME:/PATH/TO/.pgpass
|
||||
# INSTANCE=/home/postgres/db2.env:USER_NAME:/PATH/TO/.pgpass
|
||||
|
||||
# TODO @dba USERNAME in .pgpass ?
|
||||
# INSTANCE=/home/postgres/db2.env:/PATH/TO/.pgpass
|
||||
|
||||
|
||||
function postgres_main() {
|
||||
if [ -z "$DBUSER" ] || [ -z "$PGDATABASE" ] ; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
EXTRA_ARGS=""
|
||||
if [ ! -z "$PGUSER" ]; then
|
||||
EXTRA_ARGS=$EXTRA_ARGS" -U $PGUSER"
|
||||
fi
|
||||
if [ ! -z "$PGPORT" ]; then
|
||||
EXTRA_ARGS=$EXTRA_ARGS" -p $PGPORT"
|
||||
fi
|
||||
|
||||
if [ ! -z "$PGPASSFILE" ]; then
|
||||
export_PGPASSFILE="export PGPASSFILE=$PGPASSFILE; "
|
||||
fi
|
||||
|
||||
DATABASES="$(echo "SELECT datname FROM pg_database WHERE datistemplate = false;" |\
|
||||
su - "$DBUSER" -c "$export_PGPASSFILE $psql -X -d $PGDATABASE ${EXTRA_ARGS} -t -A -F';'")"
|
||||
ECHO_DATABASES="$(echo "$DATABASES" | sed 's/^/\\echo /')"
|
||||
|
||||
POSTGRES_VERSION=$(su - "$DBUSER" -c "$psql -X -V -d $PGDATABASE ${EXTRA_ARGS} | egrep -o '[0-9]{1,}\.[0-9]{1,}'")
|
||||
|
||||
postgres_sessions
|
||||
postgres_simple_queries
|
||||
postgres_stats
|
||||
postgres_version
|
||||
postgres_bloat
|
||||
}
|
||||
|
||||
|
||||
MK_CONFFILE=$MK_CONFDIR/postgres.cfg
|
||||
if [ -e "$MK_CONFFILE" ]; then
|
||||
|
||||
postgres_instances
|
||||
|
||||
DBUSER=$(grep DBUSER "$MK_CONFFILE" | sed 's/.*=//g')
|
||||
cat "$MK_CONFFILE" | while read line
|
||||
do
|
||||
case $line in
|
||||
INSTANCE*)
|
||||
instance=$line
|
||||
;;
|
||||
*)
|
||||
instance=
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ ! -z "$instance" ]; then
|
||||
instance_path=$(echo "$instance" | sed 's/.*=\(.*\):.*:.*$/\1/g')
|
||||
instance_name=$(echo "$instance_path" | sed -e 's/.*\/\(.*\)/\1/g' -e 's/\.env$//g')
|
||||
if [ ! -z "$instance_name" ]; then
|
||||
INSTANCE_SECTION="\n[[[$instance_name]]]"
|
||||
else
|
||||
INSTANCE_SECTION=""
|
||||
fi
|
||||
|
||||
psql="/$DBUSER/$(grep "^export PGVERSION=" "$instance_path" |
|
||||
sed -e 's/.*=//g' -e 's/\s*#.*$//g')/bin/psql"
|
||||
|
||||
PGUSER=$(echo "$instance" | sed 's/.*=.*:\(.*\):.*$/\1/g')
|
||||
PGPASSFILE="$(echo "$instance" | sed 's/.*=.*:.*:\(.*\)$/\1/g')"
|
||||
PGDATABASE=$(grep "^export PGDATABASE=" "$instance_path" |
|
||||
sed -e 's/.*=//g' -e 's/\s*#.*$//g')
|
||||
PGPORT=$(grep "^export PGPORT=" "$instance_path" |
|
||||
sed -e 's/.*=//g' -e 's/\s*#.*$//g')
|
||||
|
||||
# Fallback
|
||||
if [ ! -f "$psql" ]; then
|
||||
psql="$(cat $instance_path | grep "^export PGHOME=" |
|
||||
sed -e 's/.*=//g' -e 's/\s*#.*$//g')/psql"
|
||||
fi
|
||||
|
||||
postgres_main
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
else
|
||||
|
||||
if id pgsql >/dev/null 2>&1; then
|
||||
DBUSER=pgsql
|
||||
elif id postgres >/dev/null 2>&1; then
|
||||
DBUSER=postgres
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
INSTANCE_SECTION=""
|
||||
|
||||
postgres_instances "$DBUSER"
|
||||
|
||||
psql="psql"
|
||||
PGDATABASE=postgres
|
||||
postgres_main
|
||||
|
||||
fi
|
504
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_sap
Executable file
504
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_sap
Executable file
|
@ -0,0 +1,504 @@
|
|||
#!/usr/bin/python
|
||||
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# This agent plugin has been built to collect information from SAP R/3 systems
|
||||
# using RFC calls. It needs the python module sapnwrfc (available in Check_MK
|
||||
# git at agents/sap/sapnwrfc) and the nwrfcsdk (can be downloaded from SAP
|
||||
# download portal) installed to be working. You can configure the agent plugin
|
||||
# using the configuration file /etc/check_mk/sap.cfg (a sample file can be
|
||||
# found in Check_MK git at agents/sap/sap.cfg) to tell it how to connect to
|
||||
# your SAP instance and which values you want to fetch from your system to be
|
||||
# forwarded to and checked by Check_MK.
|
||||
#
|
||||
# This current agent has been developed and tested with:
|
||||
# python-sapnwrfc-0.19
|
||||
#
|
||||
# During development the "CCMS_Doku.pdf" was really helpful.
|
||||
|
||||
import os, sys, fcntl
|
||||
import time, datetime
|
||||
|
||||
# sapnwrfc needs to know where the libs are located. During
|
||||
# development the import failed, since the module did not
|
||||
# find the libraries. So we preload the library to have it
|
||||
# already loaded.
|
||||
try:
|
||||
import sapnwrfc
|
||||
except ImportError, e:
|
||||
if 'sapnwrfc.so' in str(e):
|
||||
sys.stderr.write(
|
||||
'Unable to find the library sapnwrfc.so. Maybe you need to put a file pointing to\n'
|
||||
'the sapnwrfc library directory into the /etc/ld.so.conf.d directory. For example\n'
|
||||
'create the file /etc/ld.so.conf.d/sapnwrfc.conf containing the path\n'
|
||||
'"/usr/sap/nwrfcsdk/lib" and run "ldconfig" afterwards.\n'
|
||||
)
|
||||
sys.exit(1)
|
||||
elif 'No module named sapnwrfc' in str(e):
|
||||
sys.stderr.write("Missing the Python module sapnwfrc.\n")
|
||||
sys.exit(1)
|
||||
else:
|
||||
raise
|
||||
|
||||
# #############################################################################
|
||||
|
||||
# This sign is used to separate the path parts given in the config
|
||||
SEPARATOR = '/'
|
||||
|
||||
# This are the different classes of monitoring objects which
|
||||
# can be found in the tree.
|
||||
#
|
||||
# Summarizs information from several subnodes
|
||||
MTE_SUMMARY = '050'
|
||||
# A monitoring object which has several subnodes which lead to the status
|
||||
# of this object. For example it is the "CPU" object on a host
|
||||
MTE_MON_OBJ = '070'
|
||||
# Contains performance information (which can be used to create graphs from)
|
||||
MTE_PERFORMANCE = '100'
|
||||
# Might contain several messages
|
||||
MTE_MSG_CONTAINER = '101'
|
||||
# Contains a single status message
|
||||
MTE_SINGLE_MSG = '102'
|
||||
# This is a long text label without status
|
||||
MTE_LONG_TXT = '110'
|
||||
# This is a short text label without status
|
||||
MTE_SHORT_TXT = '111'
|
||||
# Is a "folder" which has no own state, just computed by its childs
|
||||
MTE_VIRTUAL = '199'
|
||||
|
||||
# This map converts between the SAP color codes (key values) and the
|
||||
# nagios state codes and strings
|
||||
STATE_VALUE_MAP = {
|
||||
0: (0, 'OK'), # GRAY (inactive or no current info available) -> OK
|
||||
1: (0, 'OK'), # GREEN -> OK
|
||||
2: (1, 'WARN'), # YELLOW -> WARNING
|
||||
3: (2, 'CRIT'), # RED -> CRITICAL
|
||||
}
|
||||
|
||||
STATE_LOGWATCH_MAP = [ 'O', 'O', 'W', 'C' ]
|
||||
|
||||
# Monitoring objects of these classes are skipped during processing
|
||||
SKIP_MTCLASSES = [
|
||||
MTE_VIRTUAL,
|
||||
MTE_SUMMARY,
|
||||
MTE_MON_OBJ,
|
||||
MTE_SHORT_TXT,
|
||||
MTE_LONG_TXT,
|
||||
]
|
||||
|
||||
MK_CONFDIR = os.getenv("MK_CONFDIR") or "/etc/check_mk"
|
||||
MK_VARDIR = os.getenv("MK_VARDIR") or "/var/lib/check_mk_agent"
|
||||
|
||||
STATE_FILE = MK_VARDIR + '/sap.state'
|
||||
state_file_changed = False
|
||||
|
||||
# #############################################################################
|
||||
|
||||
# Settings to be used to connect to the SAP R/3 host.
|
||||
local_cfg = {
|
||||
'ashost': 'localhost',
|
||||
'sysnr': '00',
|
||||
'client': '100',
|
||||
'user': '',
|
||||
'passwd': '',
|
||||
'trace': '3',
|
||||
'loglevel': 'warn',
|
||||
#'lang': 'EN',
|
||||
}
|
||||
|
||||
# A list of strings, while the string must match the full path to one or
|
||||
# several monitor objects. We use unix shell patterns during matching, so
|
||||
# you can use several chars as placeholders:
|
||||
#
|
||||
# * matches everything
|
||||
# ? matches any single character
|
||||
# [seq] matches any character in seq
|
||||
# [!seq] matches any character not in seq
|
||||
#
|
||||
# The * matches the whole following string and does not end on next "/".
|
||||
# For examples, take a look at the default config file (/etc/check_mk/sap.cfg).
|
||||
monitor_paths = [
|
||||
'SAP CCMS Monitor Templates/Dialog Overview/*',
|
||||
]
|
||||
monitor_types = []
|
||||
config_file = MK_CONFDIR + '/sap.cfg'
|
||||
|
||||
cfg = {}
|
||||
if os.path.exists(config_file):
|
||||
execfile(config_file)
|
||||
if type(cfg) == dict:
|
||||
cfg = [ cfg ]
|
||||
else:
|
||||
cfg = [ local_cfg ]
|
||||
|
||||
# Load the state file into memory
|
||||
try:
|
||||
states = eval(file(STATE_FILE).read())
|
||||
except IOError:
|
||||
states = {}
|
||||
|
||||
# index of all logfiles which have been found in a run. This is used to
|
||||
# remove logfiles which are not available anymore from the states dict.
|
||||
logfiles = []
|
||||
|
||||
# #############################################################################
|
||||
|
||||
#
|
||||
# HELPERS
|
||||
#
|
||||
|
||||
import fnmatch
|
||||
|
||||
def to_be_monitored(path, toplevel_match = False):
|
||||
for rule in monitor_paths:
|
||||
if toplevel_match and rule.count('/') > 1:
|
||||
rule = '/'.join(rule.split('/')[:2])
|
||||
|
||||
if fnmatch.fnmatch(path, rule):
|
||||
return True
|
||||
return False
|
||||
|
||||
def node_path(tree, node, path = ''):
|
||||
if path:
|
||||
path = node['MTNAMESHRT'].rstrip() + SEPARATOR + path
|
||||
else:
|
||||
path = node['MTNAMESHRT'].rstrip()
|
||||
|
||||
if node['ALPARINTRE'] > 0:
|
||||
parent_node = tree[node['ALPARINTRE'] - 1]
|
||||
return node_path(tree, parent_node, path)
|
||||
return path
|
||||
|
||||
#
|
||||
# API ACCESS FUNCTIONS
|
||||
#
|
||||
|
||||
def query(what, params, debug = False):
|
||||
fd = conn.discover(what)
|
||||
|
||||
if debug:
|
||||
sys.stdout.write("Name: %s Params: %s\n" % (fd.name, fd.handle.parameters))
|
||||
sys.stdout.write("Given-Params: %s\n" % params)
|
||||
|
||||
f = fd.create_function_call()
|
||||
for key, val in params.items():
|
||||
getattr(f, key)(val)
|
||||
f.invoke()
|
||||
|
||||
ret = f.RETURN.value
|
||||
if ret['TYPE'] == 'E':
|
||||
sys.stderr.write("ERROR: %s\n" % ret['MESSAGE'].strip())
|
||||
|
||||
return f
|
||||
|
||||
def login():
|
||||
f = query('BAPI_XMI_LOGON', {
|
||||
'EXTCOMPANY': 'Mathias Kettner GmbH',
|
||||
'EXTPRODUCT': 'Check_MK SAP Agent',
|
||||
'INTERFACE': 'XAL',
|
||||
'VERSION': '1.0',
|
||||
})
|
||||
#sys.stdout.write("%s\n" % f.RETURN)
|
||||
return f.SESSIONID.value
|
||||
|
||||
def logout():
|
||||
query('BAPI_XMI_LOGOFF', {
|
||||
'INTERFACE': 'XAL',
|
||||
})
|
||||
|
||||
def mon_list(cfg):
|
||||
f = query("BAPI_SYSTEM_MON_GETLIST", {
|
||||
'EXTERNAL_USER_NAME': cfg['user'],
|
||||
})
|
||||
l = []
|
||||
for mon in f.MONITOR_NAMES.value:
|
||||
l.append((mon["MS_NAME"].rstrip(), mon["MONI_NAME"].rstrip()))
|
||||
return l
|
||||
|
||||
#def ms_list( cfg ):
|
||||
# f = query("BAPI_SYSTEM_MS_GETLIST", {
|
||||
# 'EXTERNAL_USER_NAME': cfg['user'],
|
||||
# })
|
||||
# l = []
|
||||
# for ms in f.MONITOR_SETS.value:
|
||||
# l.append(ms['NAME'].rstrip())
|
||||
# return l
|
||||
|
||||
def mon_tree(cfg, ms_name, mon_name):
|
||||
f = query("BAPI_SYSTEM_MON_GETTREE", {
|
||||
'EXTERNAL_USER_NAME': cfg['user'],
|
||||
'MONITOR_NAME': {"MS_NAME": ms_name, "MONI_NAME": mon_name},
|
||||
})
|
||||
tree = f.TREE_NODES.value
|
||||
for node in tree:
|
||||
node['PATH'] = ms_name + SEPARATOR + node_path(tree, node)
|
||||
return tree
|
||||
|
||||
def tid(node):
|
||||
return {
|
||||
'MTSYSID': node['MTSYSID'].strip(),
|
||||
'MTMCNAME': node['MTMCNAME'].strip(),
|
||||
'MTNUMRANGE': node['MTNUMRANGE'].strip(),
|
||||
'MTUID': node['MTUID'].strip(),
|
||||
'MTCLASS': node['MTCLASS'].strip(),
|
||||
'MTINDEX': node['MTINDEX'].strip(),
|
||||
'EXTINDEX': node['EXTINDEX'].strip(),
|
||||
}
|
||||
|
||||
def mon_perfdata(cfg, node):
|
||||
f = query('BAPI_SYSTEM_MTE_GETPERFCURVAL', {
|
||||
'EXTERNAL_USER_NAME': cfg['user'],
|
||||
'TID': tid(node),
|
||||
})
|
||||
value = f.CURRENT_VALUE.value['LASTPERVAL']
|
||||
|
||||
f = query('BAPI_SYSTEM_MTE_GETPERFPROP', {
|
||||
'EXTERNAL_USER_NAME': cfg['user'],
|
||||
'TID': tid(node),
|
||||
})
|
||||
if f.PROPERTIES.value['DECIMALS'] != 0:
|
||||
value = (value + 0.0) / 10**f.PROPERTIES.value['DECIMALS']
|
||||
uom = f.PROPERTIES.value['VALUNIT'].strip()
|
||||
|
||||
return value, uom
|
||||
|
||||
def mon_msg(cfg, node):
|
||||
f = query('BAPI_SYSTEM_MTE_GETSMVALUE', {
|
||||
'EXTERNAL_USER_NAME': cfg['user'],
|
||||
'TID': tid(node),
|
||||
})
|
||||
data = f.VALUE.value
|
||||
dt = parse_dt(data['SMSGDATE'], data['SMSGTIME'])
|
||||
return (dt, data['MSG'].strip())
|
||||
|
||||
def parse_dt(d, t):
|
||||
d = d.strip()
|
||||
t = t.strip()
|
||||
if not d or not t:
|
||||
return None
|
||||
else:
|
||||
return datetime.datetime(*time.strptime(d + t, '%Y%m%d%H%M%S')[:6])
|
||||
|
||||
def mon_alerts(cfg, node):
|
||||
f = query('BAPI_SYSTEM_MTE_GETALERTS', {
|
||||
'EXTERNAL_USER_NAME': cfg['user'],
|
||||
'TID': tid(node),
|
||||
})
|
||||
return f.ALERTS.value
|
||||
|
||||
def aid(alert):
|
||||
return {
|
||||
"ALSYSID": alert["ALSYSID"],
|
||||
"MSEGNAME": alert["MSEGNAME"],
|
||||
"ALUNIQNUM": alert["ALUNIQNUM"],
|
||||
"ALINDEX": alert["ALINDEX"],
|
||||
"ALERTDATE": alert["ALERTDATE"],
|
||||
"ALERTTIME": alert["ALERTTIME"],
|
||||
}
|
||||
|
||||
def alert_details(cfg, alert):
|
||||
f = query('BAPI_SYSTEM_ALERT_GETDETAILS', {
|
||||
'EXTERNAL_USER_NAME': cfg['user'],
|
||||
'AID': aid(alert),
|
||||
})
|
||||
#prop = f.PROPERTIES.value
|
||||
state = f.VALUE.value
|
||||
msg = f.XMI_EXT_MSG.value['MSG'].strip()
|
||||
return state, msg
|
||||
|
||||
def process_alerts(cfg, logs, ms_name, mon_name, node, alerts):
|
||||
global state_file_changed
|
||||
|
||||
sid = node["MTSYSID"].strip() or 'Other'
|
||||
context = node["MTMCNAME"].strip() or 'Other'
|
||||
path = node["PATH"]
|
||||
|
||||
# Use the sid as hostname for the logs
|
||||
hostname = sid
|
||||
logfile = context + "/" + path
|
||||
|
||||
logfiles.append((hostname, logfile))
|
||||
|
||||
logs.setdefault(sid, {})
|
||||
logs[hostname][logfile] = []
|
||||
newest_log_dt = None
|
||||
for alert in alerts:
|
||||
dt = parse_dt(alert['ALERTDATE'], alert['ALERTTIME'])
|
||||
|
||||
if (hostname, logfile) in states and states[(hostname, logfile)] >= dt:
|
||||
continue # skip log messages which are older than the last cached date
|
||||
|
||||
if not newest_log_dt or dt > newest_log_dt:
|
||||
newest_log_dt = dt # store the newest log of this run
|
||||
|
||||
alert_state, alert_msg = alert_details(cfg, alert)
|
||||
# Format lines to "logwatch" format
|
||||
logs[hostname][logfile].append('%s %s %s' % (STATE_LOGWATCH_MAP[alert_state['VALUE']],
|
||||
dt.strftime("%Y-%m-%d %H:%M:%S"), alert_msg))
|
||||
|
||||
if newest_log_dt:
|
||||
# Write newest log age to cache to prevent double processing of logs
|
||||
states[(hostname, logfile)] = newest_log_dt
|
||||
state_file_changed = True
|
||||
return logs
|
||||
|
||||
|
||||
|
||||
def check(cfg):
|
||||
global conn
|
||||
conn = sapnwrfc.base.rfc_connect(cfg)
|
||||
login()
|
||||
|
||||
logs = {}
|
||||
sap_data = {}
|
||||
|
||||
# This loop is used to collect all information from SAP
|
||||
for ms_name, mon_name in mon_list(cfg):
|
||||
path = ms_name + SEPARATOR + mon_name
|
||||
if not to_be_monitored(path, True):
|
||||
continue
|
||||
|
||||
tree = mon_tree(cfg, ms_name, mon_name)
|
||||
for node in tree:
|
||||
if not to_be_monitored(node['PATH']):
|
||||
continue
|
||||
#sys.stdout.write("%s\n" % node["PATH"])
|
||||
|
||||
status_details = ''
|
||||
perfvalue = '-'
|
||||
uom = '-'
|
||||
|
||||
# Use precalculated states
|
||||
state = {
|
||||
'VALUE': node['ACTUALVAL'],
|
||||
'SEVERITY': node['ACTUALSEV'],
|
||||
}
|
||||
|
||||
if state['VALUE'] not in STATE_VALUE_MAP:
|
||||
sys.stdout.write('UNHANDLED STATE VALUE\n')
|
||||
sys.exit(1)
|
||||
|
||||
#
|
||||
# Handle different object classes individually
|
||||
# to get details about them
|
||||
#
|
||||
|
||||
if monitor_types and node['MTCLASS'] not in monitor_types:
|
||||
continue # Skip unwanted classes if class filtering is enabled
|
||||
|
||||
if node['MTCLASS'] == MTE_PERFORMANCE:
|
||||
perfvalue, this_uom = mon_perfdata(cfg, node)
|
||||
uom = this_uom and this_uom or uom
|
||||
|
||||
elif node['MTCLASS'] == MTE_SINGLE_MSG:
|
||||
status_details = "%s: %s" % mon_msg(cfg, node)
|
||||
|
||||
elif node['MTCLASS'] == MTE_MSG_CONTAINER:
|
||||
|
||||
alerts = mon_alerts(cfg, node)
|
||||
logs = process_alerts(cfg, logs, ms_name, mon_name, node, alerts)
|
||||
if len(alerts) > 0:
|
||||
last_alert = alerts[-1]
|
||||
dt = parse_dt(last_alert["ALERTDATE"], last_alert["ALERTTIME"])
|
||||
alert_state, alert_msg = alert_details(cfg, last_alert)
|
||||
last_msg = '%s: %s - %s' % (dt, STATE_VALUE_MAP[alert_state['VALUE']][1], alert_msg)
|
||||
|
||||
status_details = '%d Messages, Last: %s' % (len(alerts), last_msg)
|
||||
else:
|
||||
status_details = 'The log is empty'
|
||||
|
||||
elif node['MTCLASS'] not in SKIP_MTCLASSES:
|
||||
# Add an error to output on unhandled classes
|
||||
status_details = "UNHANDLED MTCLASS", node['MTCLASS']
|
||||
|
||||
if node['MTCLASS'] not in SKIP_MTCLASSES:
|
||||
sid = node["MTSYSID"].strip() or 'Other'
|
||||
context = node["MTMCNAME"].strip() or 'Other'
|
||||
path = node["PATH"]
|
||||
|
||||
sap_data.setdefault(sid, [])
|
||||
sap_data[sid].append("%s\t%d\t%3d\t%s\t%s\t%s\t%s" % (context, state['VALUE'],
|
||||
state['SEVERITY'], path, perfvalue, uom, status_details))
|
||||
|
||||
|
||||
for host, host_sap in sap_data.items():
|
||||
sys.stdout.write('<<<<%s>>>>\n' % host)
|
||||
sys.stdout.write('<<<sap:sep(9)>>>\n')
|
||||
sys.stdout.write('%s\n' % '\n'.join(host_sap))
|
||||
sys.stdout.write('<<<<>>>>\n')
|
||||
|
||||
for host, host_logs in logs.items():
|
||||
sys.stdout.write('<<<<%s>>>>\n' % host)
|
||||
sys.stdout.write('<<<logwatch>>>\n')
|
||||
for log, lines in host_logs.items():
|
||||
sys.stdout.write('[[[%s]]]\n' % log)
|
||||
if lines:
|
||||
sys.stdout.write('\n'.join(lines) + '\n')
|
||||
sys.stdout.write('<<<<>>>>\n')
|
||||
|
||||
logout()
|
||||
conn.close()
|
||||
|
||||
# It is possible to configure multiple SAP instances to monitor. Loop them all, but
|
||||
# do not terminate when one connection failed
|
||||
processed_all = True
|
||||
try:
|
||||
for entry in cfg:
|
||||
try:
|
||||
check(entry)
|
||||
sys.stdout.write('<<<sap_state:sep(9)>>>\n%s\tOK\n' % entry['ashost'])
|
||||
except sapnwrfc.RFCCommunicationError, e:
|
||||
sys.stderr.write('ERROR: Unable to connect (%s)\n' % e)
|
||||
sys.stdout.write('<<<sap_state:sep(9)>>>\n%s\tUnable to connect (%s)\n' %\
|
||||
(entry['ashost'], e))
|
||||
processed_all = False
|
||||
except Exception, e:
|
||||
sys.stderr.write('ERROR: Unhandled exception (%s)\n' % e)
|
||||
sys.stdout.write('<<<sap_state:sep(9)>>>\n%s\tUnhandled exception (%s)\n' %\
|
||||
(entry['ashost'], e))
|
||||
processed_all = False
|
||||
|
||||
# Now check whether or not an old logfile needs to be removed. This can only
|
||||
# be done this way, when all hosts have been reached. Otherwise the cleanup
|
||||
# is skipped.
|
||||
if processed_all:
|
||||
for key in states.keys():
|
||||
if key not in logfiles:
|
||||
state_file_changed = True
|
||||
del states[key]
|
||||
|
||||
# Only write the state file once per run. And only when it has been changed
|
||||
if state_file_changed:
|
||||
new_file = STATE_FILE + '.new'
|
||||
fd = os.open(new_file, os.O_WRONLY | os.O_CREAT)
|
||||
fcntl.flock(fd, fcntl.LOCK_EX)
|
||||
os.write(fd, repr(states))
|
||||
os.close(fd)
|
||||
os.rename(STATE_FILE+'.new', STATE_FILE)
|
||||
|
||||
except Exception, e:
|
||||
sys.stderr.write('ERROR: Unhandled exception (%s)\n' % e)
|
||||
|
||||
sys.exit(0)
|
78
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_sap.aix
Executable file
78
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_sap.aix
Executable file
|
@ -0,0 +1,78 @@
|
|||
#!/bin/bash
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
# cat sapservices
|
||||
##!/bin/sh
|
||||
#LIBPATH=/usr/sap/C01/DVEBMGS25/exe:$LIBPATH; export LIBPATH; /usr/sap/C01/DVEBMGS25/exe/sapstartsrv pf=/usr/sap/C01/SYS/profile/START_DVEBMGS25_sap10c1 -D -u c01adm
|
||||
#LIBPATH=/usr/sap/DC1/SMDA98/exe:$LIBPATH; export LIBPATH; /usr/sap/DC1/SMDA98/exe/sapstartsrv pf=/usr/sap/DC1/SYS/profile/DC1_SMDA98_sap10c1 -D -u dc1adm
|
||||
#LIBPATH=/usr/sap/C02/DVEBMGS37/exe:$LIBPATH; export LIBPATH; /usr/sap/C02/DVEBMGS37/exe/sapstartsrv pf=/usr/sap/C02/SYS/profile/START_DVEBMGS37_sap10c1 -D -u c02adm
|
||||
#LIBPATH=/usr/sap/DAA/SMDA97/exe:$LIBPATH; export LIBPATH; /usr/sap/DAA/SMDA97/exe/sapstartsrv pf=/usr/sap/DAA/SYS/profile/DAA_SMDA97_sap10c1 -D -u daaadm
|
||||
#LIBPATH=/usr/sap/DDB/SMDA96/exe:$LIBPATH; export LIBPATH; /usr/sap/DDB/SMDA96/exe/sapstartsrv pf=/usr/sap/DDB/SYS/profile/DDB_SMDA96_sap10c1d -D -u ddbadm
|
||||
|
||||
# <<<aix_sap_processlist:sep(44)>>>
|
||||
# [69]
|
||||
# 05.06.2015 05:44:36
|
||||
# GetProcessList
|
||||
# OK
|
||||
# name, description, dispstatus, textstatus, starttime, elapsedtime, pid
|
||||
# msg_server, MessageServer, GREEN, Running, 2015 06 01 02:28:51, 99:15:45, 17563810
|
||||
# enserver, EnqueueServer, GREEN, Running, 2015 06 01 02:28:51, 99:15:45, 15466710
|
||||
# gwrd, Gateway, GREEN, Running, 2015 06 01 02:28:51, 99:15:45, 25428046
|
||||
# [68]
|
||||
# 05.06.2015 05:44:36
|
||||
# GetProcessList
|
||||
# OK
|
||||
# name, description, dispstatus, textstatus, starttime, elapsedtime, pid
|
||||
# jstart, J2EE Server, GREEN, All processes running, 2015 06 01 02:29:06, 99:15:30, 18087996
|
||||
# igswd_mt, IGS Watchdog, GREEN, Running, 2015 06 01 02:29:06, 99:15:30, 9765042
|
||||
|
||||
#
|
||||
# <<<aix_sap_processlist:sep(44)>>>
|
||||
# GetProcessList
|
||||
# FAIL: NIECONN_REFUSED (Connection refused), NiRawConnect failed in plugin_fopen()
|
||||
|
||||
sapservices="/usr/sap/sapservices"
|
||||
|
||||
if [ -r "$sapservices" ]; then
|
||||
echo "<<<aix_sap_processlist:sep(44)>>>"
|
||||
# loop over ids
|
||||
cat $sapservices | while read LINE
|
||||
do
|
||||
command=$(echo $LINE | grep "^LIBPATH=/usr/sap/" | grep -v "^LIBPATH=/usr/sap/D" | awk -F" " '{print $5}')
|
||||
if [ -n "$command" ]; then
|
||||
id2=$(echo $command | awk -F"/" '{print $4}')
|
||||
path=$(echo "/sapmnt/$id2/exe")
|
||||
sappfpar=$(find $path -name sappfpar | head -1)
|
||||
sapcontrol=$(find $path -name sapcontrol | head -1)
|
||||
libpath=$(find $path -name libicuuc\*.a | head -1 | sed -e 's,/[^ /]*$,,')
|
||||
id=$(LIBPATH=$LIBPATH:$libpath $sappfpar SAPSYSTEM $command)
|
||||
echo -n "[$id]"
|
||||
LIBPATH=$LIBPATH:$libpath $sapcontrol -nr $id -function GetProcessList
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
|
143
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_sap_hana
Executable file
143
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_sap_hana
Executable file
|
@ -0,0 +1,143 @@
|
|||
#!/bin/bash
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2017 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
|
||||
# .--config--------------------------------------------------------------.
|
||||
# | __ _ |
|
||||
# | ___ ___ _ __ / _(_) __ _ |
|
||||
# | / __/ _ \| '_ \| |_| |/ _` | |
|
||||
# | | (_| (_) | | | | _| | (_| | |
|
||||
# | \___\___/|_| |_|_| |_|\__, | |
|
||||
# | |___/ |
|
||||
# '----------------------------------------------------------------------'
|
||||
|
||||
|
||||
# Config might include
|
||||
# DB_USER_hpy=foo
|
||||
# DB_PASSWORD_hpy=bar
|
||||
if [ -f $MK_CONFDIR/sap_hana.cfg ];
|
||||
then
|
||||
. $MK_CONFDIR/sap_hana.cfg
|
||||
fi
|
||||
|
||||
|
||||
LSSAP=/usr/sap/hostctrl/exe/lssap
|
||||
if [[ ! -x $LSSAP ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
#.
|
||||
# .--queries-------------------------------------------------------------.
|
||||
# | _ |
|
||||
# | __ _ _ _ ___ _ __(_) ___ ___ |
|
||||
# | / _` | | | |/ _ \ '__| |/ _ \/ __| |
|
||||
# | | (_| | |_| | __/ | | | __/\__ \ |
|
||||
# | \__, |\__,_|\___|_| |_|\___||___/ |
|
||||
# | |_| |
|
||||
# '----------------------------------------------------------------------'
|
||||
|
||||
|
||||
# Just do: su - sidadm -c "$CMD"
|
||||
function process_list () {
|
||||
echo "<<<sap_hana_process_list:sep(44)>>>"
|
||||
su - $1 -c "sapcontrol -nr $2 -function GetProcessList"
|
||||
}
|
||||
|
||||
|
||||
function hdb_version () {
|
||||
echo "<<<sap_hana_version:sep(58)>>>"
|
||||
su - $1 -c "HDB version"
|
||||
}
|
||||
|
||||
|
||||
# Do: sudo -i -u sidadm hdbsql -n localhost -i 65 -u <dbuser> -p '<dbpassword>' -j -a -x
|
||||
function full_backup () {
|
||||
local sidadm=$1
|
||||
local inst_nr=$2
|
||||
local db_user=$3
|
||||
local db_password="$4"
|
||||
echo "<<<sap_hana_full_backup:sep(44)>>>"
|
||||
sudo -i -u ${sidadm} hdbsql -n localhost -i ${inst_nr} -u ${db_user} -p "${db_password}" -j -a -x "SELECT TO_DATE(SYS_END_TIME), days_between(SYS_END_TIME,CURRENT_TIMESTAMP) ,seconds_between(SYS_START_TIME,SYS_END_TIME), STATE_NAME,COMMENT FROM M_BACKUP_CATALOG WHERE ENTRY_TYPE_NAME = 'complete data backup' AND SYS_START_TIME = (SELECT MAX(SYS_START_TIME) FROM M_BACKUP_CATALOG WHERE ENTRY_TYPE_NAME = 'complete data backup');"
|
||||
}
|
||||
|
||||
|
||||
function sap_hana_mem () {
|
||||
local sidadm=$1
|
||||
local inst_nr=$2
|
||||
local db_user=$3
|
||||
local db_password="$4"
|
||||
echo "<<<sap_hana_mem:sep(44)>>>"
|
||||
echo "[[[resident]]]"
|
||||
sudo -i -u ${sidadm} hdbsql -n localhost -i ${inst_nr} -u ${db_user} -p "${db_password}" -j -a -x "SELECT HOST, ROUND(SUM(PHYSICAL_MEMORY_SIZE/1024/1024/1024),2) FROM M_SERVICE_MEMORY GROUP BY HOST;"
|
||||
echo "[[[database]]]"
|
||||
sudo -i -u ${sidadm} hdbsql -n localhost -i ${inst_nr} -u ${db_user} -p "${db_password}" -j -a -x "select HOST, round(INSTANCE_TOTAL_MEMORY_ALLOCATED_SIZE/(1024*1024*1024), 2), round(ALLOCATION_LIMIT/(1024*1024*1024), 2), ROUND((USED_PHYSICAL_MEMORY + FREE_PHYSICAL_MEMORY)/1024/1024/1024,2) from M_HOST_RESOURCE_UTILIZATION;"
|
||||
}
|
||||
|
||||
|
||||
|
||||
function sap_hana_filesystem () {
|
||||
local sidadm=$1
|
||||
local inst_nr=$2
|
||||
local db_user=$3
|
||||
local db_password="$4"
|
||||
echo "<<<sap_hana_filesystem:sep(44)>>>"
|
||||
sudo -i -u ${sidadm} hdbsql -n localhost -i ${inst_nr} -u ${db_user} -p "${db_password}" -j -a -x "select D1.HOST, D1.USAGE_TYPE, ROUND(D2.USED_SIZE/1024/1024/1024,2),ROUND(D1.TOTAL_SIZE/1024/1024/1024,2) FROM M_DISKS AS D1 INNER JOIN M_DISK_USAGE AS D2 ON D1.USAGE_TYPE = D2.USAGE_TYPE;"
|
||||
}
|
||||
|
||||
|
||||
#.
|
||||
# .--main----------------------------------------------------------------.
|
||||
# | _ |
|
||||
# | _ __ ___ __ _(_)_ __ |
|
||||
# | | '_ ` _ \ / _` | | '_ \ |
|
||||
# | | | | | | | (_| | | | | | |
|
||||
# | |_| |_| |_|\__,_|_|_| |_| |
|
||||
# | |
|
||||
# '----------------------------------------------------------------------'
|
||||
|
||||
|
||||
echo "<<<sap_hana_products>>>"
|
||||
$LSSAP
|
||||
|
||||
for line in $($LSSAP | awk -F"|" '{if ($0 ~/\//) print tolower($1)"adm|"$2}' | sed "s/\s*//g")
|
||||
do
|
||||
sidadm=$(echo "$line" | cut -d"|" -f1)
|
||||
sidadm_short=$(echo "$sidadm" | sed "s/adm$//")
|
||||
inst_nr=$(echo "$line" | cut -d"|" -f2)
|
||||
process_list $sidadm $inst_nr
|
||||
hdb_version $sidadm
|
||||
|
||||
DB_USER=DB_USER_$sidadm_short
|
||||
DB_USER=${!DB_USER}
|
||||
DB_PASSWORD=DB_PASSWORD_$sidadm_short
|
||||
DB_PASSWORD=${!DB_PASSWORD}
|
||||
if [ -n "$DB_USER" ] && [ -n "$DB_PASSWORD" ];
|
||||
then
|
||||
full_backup $sidadm $inst_nr ${DB_USER} ${DB_PASSWORD}
|
||||
sap_hana_mem $sidadm $inst_nr ${DB_USER} ${DB_PASSWORD}
|
||||
sap_hana_filesystem $sidadm $inst_nr ${DB_USER} ${DB_PASSWORD}
|
||||
fi
|
||||
done
|
41
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_saprouter
Executable file
41
ansible/roles/elnappo.check_mk_agent/files/plugins/mk_saprouter
Executable file
|
@ -0,0 +1,41 @@
|
|||
#!/bin/bash
|
||||
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||
# +------------------------------------------------------------------+
|
||||
# | ____ _ _ __ __ _ __ |
|
||||
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
|
||||
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
|
||||
# | | |___| | | | __/ (__| < | | | | . \ |
|
||||
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
|
||||
# | |
|
||||
# | Copyright Mathias Kettner 2016 mk@mathias-kettner.de |
|
||||
# +------------------------------------------------------------------+
|
||||
#
|
||||
# This file is part of Check_MK.
|
||||
# The official homepage is at http://mathias-kettner.de/check_mk.
|
||||
#
|
||||
# check_mk 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 in version 2. check_mk is distributed
|
||||
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
|
||||
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
|
||||
# tails. You should have received a copy of the GNU General Public
|
||||
# License along with GNU Make; see the file COPYING. If not, write
|
||||
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA.
|
||||
|
||||
|
||||
# Plugin for SAP router
|
||||
|
||||
|
||||
. $MK_CONFDIR/saprouter.cfg || exit 1
|
||||
|
||||
|
||||
if [ ! -z "$SAPROUTER_USER" -a ! -z "$SAPGENPSE_PATH" ]
|
||||
then
|
||||
if type ${SAPGENPSE_PATH}/sapgenpse > /dev/null
|
||||
then
|
||||
echo "<<<saprouter_cert>>>"
|
||||
su - $SAPROUTER_USER -c "${SAPGENPSE_PATH}/sapgenpse get_my_name -n validity 2>&1"
|
||||
fi
|
||||
fi
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user