mirror of
https://github.com/centreon/centreon-plugins.git
synced 2025-04-08 17:06:05 +02:00
Release 20250400 (#5542)
This commit is contained in:
commit
d894389296
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
@ -21,3 +21,6 @@ tests/** @centreon/owners-robot-e2e
|
||||
packaging/** @centreon/owners-perl
|
||||
selinux/** @centreon/owners-pipelines
|
||||
.github/scripts/pod_spell_check.t @centreon/owners-perl
|
||||
|
||||
.gitleaks.toml @centreon/owners-security
|
||||
.gitleaksignore @centreon/owners-security
|
||||
|
2
.github/actions/merge-artifacts/action.yml
vendored
2
.github/actions/merge-artifacts/action.yml
vendored
@ -18,7 +18,7 @@ runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Download Artifacts
|
||||
uses: actions/download-artifact@f44cd7b40bfd40b6aa1cc1b9b5b7bf03d3c67110 # v4.1.0
|
||||
uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9
|
||||
with:
|
||||
pattern: ${{ inputs.source_name_pattern }}*
|
||||
path: ${{ inputs.target_name }}
|
||||
|
6
.github/actions/package-delivery/action.yml
vendored
6
.github/actions/package-delivery/action.yml
vendored
@ -77,7 +77,7 @@ runs:
|
||||
|
||||
- if: ${{ inputs.stability != 'stable' }}
|
||||
name: Restore packages from cache
|
||||
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
uses: actions/cache/restore@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ./*.${{ steps.parse-distrib.outputs.package_extension }}
|
||||
key: ${{ inputs.cache_key }}
|
||||
@ -107,7 +107,7 @@ runs:
|
||||
}
|
||||
|
||||
- name: Download packages from testing
|
||||
if: ${{ inputs.stability == 'stable' && github.event_name == 'push' && inputs.distrib != 'jammy' }}
|
||||
if: ${{ inputs.stability == 'stable' && github.event_name == 'push' && (inputs.distrib != 'jammy' || inputs.distrib != 'noble') }}
|
||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||
with:
|
||||
script: |
|
||||
@ -170,7 +170,7 @@ runs:
|
||||
- name: Publish packages to ${{ inputs.stability }}
|
||||
if: |
|
||||
contains(fromJson('["testing", "unstable"]'), inputs.stability) ||
|
||||
(inputs.stability == 'stable' && github.event_name == 'push' && inputs.distrib != 'jammy')
|
||||
(inputs.stability == 'stable' && github.event_name == 'push' && (inputs.distrib != 'jammy' || inputs.distrib != 'noble'))
|
||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||
with:
|
||||
script: |
|
||||
|
2
.github/actions/package-nfpm/action.yml
vendored
2
.github/actions/package-nfpm/action.yml
vendored
@ -122,7 +122,7 @@ runs:
|
||||
done
|
||||
shell: bash
|
||||
|
||||
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
- uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ./*.${{ inputs.package_extension }}
|
||||
key: ${{ inputs.cache_key }}
|
||||
|
5
.github/actions/parse-distrib/action.yml
vendored
5
.github/actions/parse-distrib/action.yml
vendored
@ -54,6 +54,11 @@ runs:
|
||||
PACKAGE_DISTRIB_NAME="0ubuntu.22.04"
|
||||
PACKAGE_EXTENSION="deb"
|
||||
DISTRIB_FAMILY="ubuntu"
|
||||
elif [[ "${{ inputs.distrib }}" == "noble" ]]; then
|
||||
PACKAGE_DISTRIB_SEPARATOR="-"
|
||||
PACKAGE_DISTRIB_NAME="0ubuntu.24.04"
|
||||
PACKAGE_EXTENSION="deb"
|
||||
DISTRIB_FAMILY="ubuntu"
|
||||
else
|
||||
echo "::error::Distrib ${{ inputs.distrib }} cannot be parsed"
|
||||
exit 1
|
||||
|
4
.github/actions/promote-to-stable/action.yml
vendored
4
.github/actions/promote-to-stable/action.yml
vendored
@ -66,14 +66,14 @@ runs:
|
||||
shell: bash
|
||||
|
||||
- name: Promote DEB package to stable
|
||||
if: ${{ contains(fromJSON('["bullseye", "bookworm", "jammy"]'), inputs.distrib) }}
|
||||
if: ${{ contains(fromJSON('["bullseye", "bookworm", "jammy", "noble"]'), inputs.distrib) }}
|
||||
run: |
|
||||
set -eux
|
||||
|
||||
echo "[DEBUG] - Distrib: ${{ inputs.distrib }}"
|
||||
echo "[DEBUG] - Distrib: ${{ inputs.module }}"
|
||||
|
||||
if [[ "${{ inputs.distrib }}" == "jammy" ]]; then
|
||||
if [[ "${{ inputs.distrib }}" == "jammy" || "${{ inputs.distrib }}" == "noble" ]]; then
|
||||
repo="ubuntu-plugins"
|
||||
else
|
||||
repo="apt-plugins"
|
||||
|
6
.github/actions/test-plugins/action.yml
vendored
6
.github/actions/test-plugins/action.yml
vendored
@ -16,7 +16,7 @@ runs:
|
||||
steps:
|
||||
|
||||
- name: get the cached plugin
|
||||
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
uses: actions/cache/restore@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ./*.${{ inputs.package-extension }}
|
||||
key: ${{ inputs.cache-key }}
|
||||
@ -24,4 +24,6 @@ runs:
|
||||
|
||||
- name: Install, test and remove plugin
|
||||
shell: bash
|
||||
run: python3 .github/scripts/test-all-plugins.py ${{ inputs.package-extension }} ${{ inputs.plugin-list }}
|
||||
run: |
|
||||
[[ -f /.venv/bin/activate ]] && source /.venv/bin/activate
|
||||
python3 .github/scripts/test-all-plugins.py ${{ inputs.package-extension }} ${{ inputs.plugin-list }}
|
||||
|
30
.github/docker/packaging/Dockerfile.packaging-plugins-java-noble
vendored
Normal file
30
.github/docker/packaging/Dockerfile.packaging-plugins-java-noble
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
ARG REGISTRY_URL
|
||||
|
||||
FROM ${REGISTRY_URL}/ubuntu:noble
|
||||
|
||||
RUN bash -e <<EOF
|
||||
|
||||
apt-get update
|
||||
apt-get install -y \
|
||||
ca-certificates \
|
||||
git \
|
||||
openjdk-17-jdk \
|
||||
wget \
|
||||
zstd
|
||||
|
||||
cd /usr/local/src
|
||||
wget https://dlcdn.apache.org/maven/maven-3/3.8.8/binaries/apache-maven-3.8.8-bin.tar.gz
|
||||
tar zxf apache-maven-3.8.8-bin.tar.gz
|
||||
ln -s /usr/local/src/apache-maven-3.8.8/bin/mvn /usr/bin/mvn
|
||||
rm -f apache-maven-3.8.8-bin.tar.gz
|
||||
|
||||
echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | tee /etc/apt/sources.list.d/goreleaser.list
|
||||
|
||||
apt-get update
|
||||
apt-get install -y nfpm=2.41.0
|
||||
|
||||
apt-get clean all
|
||||
|
||||
EOF
|
||||
|
||||
WORKDIR /src
|
72
.github/docker/packaging/Dockerfile.packaging-plugins-noble
vendored
Normal file
72
.github/docker/packaging/Dockerfile.packaging-plugins-noble
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
ARG REGISTRY_URL=docker.io
|
||||
|
||||
FROM ${REGISTRY_URL}/ubuntu:noble
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# fix locale
|
||||
RUN bash -e <<EOF
|
||||
|
||||
apt-get update
|
||||
apt-get install -y locales
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
|
||||
apt-get clean
|
||||
|
||||
EOF
|
||||
|
||||
ENV LANG=en_US.utf8
|
||||
|
||||
RUN bash -e <<EOF
|
||||
|
||||
apt-get update
|
||||
|
||||
echo 'http://deb.debian.org/debian' | apt-get install -y pbuilder
|
||||
|
||||
apt-get install -y \
|
||||
aptitude \
|
||||
ca-certificates \
|
||||
cpanminus \
|
||||
curl \
|
||||
debmake \
|
||||
devscripts \
|
||||
dh-make \
|
||||
dh-make-perl \
|
||||
fakeroot \
|
||||
gcc \
|
||||
git \
|
||||
git-buildpackage \
|
||||
jq \
|
||||
libapp-fatpacker-perl \
|
||||
libcurl4-openssl-dev \
|
||||
libczmq-dev \
|
||||
libczmq-dev\
|
||||
libfile-copy-recursive-perl \
|
||||
libjson-perl \
|
||||
libmodule-build-tiny-perl \
|
||||
libmodule-install-perl \
|
||||
libssh-dev \
|
||||
lintian \
|
||||
python3 \
|
||||
quilt \
|
||||
ruby \
|
||||
uuid-dev \
|
||||
zstd
|
||||
|
||||
cpanm Module::Build::Tiny
|
||||
cpanm Module::Install
|
||||
cpanm Crypt::OpenSSL::Guess
|
||||
|
||||
gem install fpm
|
||||
|
||||
echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | tee /etc/apt/sources.list.d/goreleaser.list
|
||||
apt-get update
|
||||
apt-get install -y nfpm=2.41.0
|
||||
|
||||
apt-get clean
|
||||
|
||||
EOF
|
||||
|
||||
COPY .github/patch/fpm-deb.rb.diff /tmp/fpm-deb.rb.diff
|
||||
# Patch to apply fpm fix for debian package generation while waiting for the official fix to be released (https://github.com/jordansissel/fpm/pull/1947).
|
||||
RUN patch -i /tmp/fpm-deb.rb.diff $(find / -type f -name "deb.rb") && /bin/rm -rf /tmp/fpm-deb.rb.diff
|
@ -12,7 +12,7 @@ dnf clean all
|
||||
dnf install -y python3.11 python3.11-pip
|
||||
pip3.11 install robotframework robotframework-examples
|
||||
# Install snmpsim
|
||||
pip3.11 install snmpsim-lextudio
|
||||
pip3.11 install snmpsim
|
||||
|
||||
# Install node
|
||||
curl -fsSL https://rpm.nodesource.com/setup_21.x | bash -
|
||||
|
@ -12,7 +12,7 @@ dnf clean all
|
||||
dnf install -y python3.11 python3.11-pip
|
||||
pip3.11 install robotframework robotframework-examples
|
||||
# Install snmpsim
|
||||
pip3.11 install snmpsim-lextudio
|
||||
pip3.11 install snmpsim
|
||||
|
||||
# Install node
|
||||
curl -fsSL https://rpm.nodesource.com/setup_21.x | bash -
|
||||
|
@ -28,7 +28,7 @@ apt-get install -y python3-dev python3-pip
|
||||
rm -rf /usr/lib/python3.11/EXTERNALLY-MANAGED
|
||||
pip3 install robotframework robotframework-examples
|
||||
# Install snmpsim
|
||||
pip3 install snmpsim-lextudio
|
||||
pip3 install snmpsim
|
||||
|
||||
# Install nodejs
|
||||
curl -fsSL https://deb.nodesource.com/setup_21.x | bash - &&\
|
||||
|
@ -27,7 +27,7 @@ apt-get update
|
||||
apt-get install -y python3 python3-dev python3-pip
|
||||
pip3 install robotframework robotframework-examples
|
||||
# Install snmpsim
|
||||
pip3 install snmpsim-lextudio
|
||||
pip3 install snmpsim
|
||||
|
||||
# Install nodejs
|
||||
curl -fsSL https://deb.nodesource.com/setup_21.x | bash - &&\
|
||||
|
@ -27,7 +27,7 @@ apt-get update
|
||||
apt-get install -y python3 python3-dev python3-pip
|
||||
pip3 install robotframework robotframework-examples
|
||||
# Install snmpsim
|
||||
pip3 install snmpsim-lextudio
|
||||
pip3 install snmpsim
|
||||
|
||||
# Install nodejs
|
||||
curl -fsSL https://deb.nodesource.com/setup_21.x | bash - &&\
|
||||
|
53
.github/docker/testing/Dockerfile.testing-plugins-noble
vendored
Normal file
53
.github/docker/testing/Dockerfile.testing-plugins-noble
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
ARG REGISTRY_URL=docker.io
|
||||
|
||||
FROM ${REGISTRY_URL}/ubuntu:noble
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# fix locale
|
||||
RUN bash -e <<EOF
|
||||
|
||||
apt-get update
|
||||
apt-get install -y locales libcurl4-openssl-dev curl wget zstd jq
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
|
||||
apt-get clean
|
||||
|
||||
EOF
|
||||
|
||||
ENV LANG=en_US.utf8
|
||||
|
||||
RUN bash -e <<EOF
|
||||
|
||||
# Avoid apt to clean packages cache directory
|
||||
rm -f /etc/apt/apt.conf.d/docker-clean
|
||||
|
||||
apt-get update
|
||||
# Install requirements for python virtual envs
|
||||
apt-get install -y python3-venv
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
# Install Robotframework
|
||||
apt-get install -y python3 python3-dev python3-pip
|
||||
pip3 install robotframework robotframework-examples
|
||||
# Install snmpsim
|
||||
pip3 install snmpsim
|
||||
|
||||
# Install nodejs
|
||||
curl -fsSL https://deb.nodesource.com/setup_21.x | bash - &&\
|
||||
apt-get install -y nodejs
|
||||
# Install mockoon (needs nodejs)
|
||||
npm install -g -D @mockoon/cli
|
||||
|
||||
# Add Centreon plugins repositories
|
||||
echo "deb https://packages.centreon.com/ubuntu-plugins-testing/ noble main" | tee -a /etc/apt/sources.list.d/centreon-plugins.list
|
||||
echo "deb https://packages.centreon.com/ubuntu-plugins-unstable/ noble main" | tee -a /etc/apt/sources.list.d/centreon-plugins.list
|
||||
wget -O- https://apt-key.centreon.com | gpg --dearmor | tee /etc/apt/trusted.gpg.d/centreon.gpg > /dev/null 2>&1
|
||||
apt-get update
|
||||
|
||||
mkdir -p /var/lib/centreon/centplugins/
|
||||
chmod 777 /var/lib/centreon/centplugins/
|
||||
|
||||
apt-get clean
|
||||
|
||||
EOF
|
37
.github/docker/unit-tests/Dockerfile.unit-tests-noble
vendored
Normal file
37
.github/docker/unit-tests/Dockerfile.unit-tests-noble
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
ARG REGISTRY_URL=docker.io
|
||||
|
||||
FROM ${REGISTRY_URL}/ubuntu:noble
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# fix locale
|
||||
RUN bash -e <<EOF
|
||||
|
||||
apt-get update
|
||||
apt-get install -y locales libcurl4-openssl-dev curl wget zstd jq gpg
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
|
||||
apt-get clean
|
||||
|
||||
EOF
|
||||
|
||||
ENV LANG=en_US.utf8
|
||||
|
||||
RUN bash -e <<EOF
|
||||
# Add Centreon plugins repositories
|
||||
echo "deb https://packages.centreon.com/ubuntu-plugins-stable/ noble main" | tee -a /etc/apt/sources.list.d/centreon-plugins.list
|
||||
echo "deb https://packages.centreon.com/ubuntu-plugins-testing/ noble main" | tee -a /etc/apt/sources.list.d/centreon-plugins.list
|
||||
echo "deb https://packages.centreon.com/ubuntu-plugins-unstable/ noble main" | tee -a /etc/apt/sources.list.d/centreon-plugins.list
|
||||
wget -O- https://apt-key.centreon.com | gpg --dearmor | tee /etc/apt/trusted.gpg.d/centreon.gpg > /dev/null 2>&1
|
||||
|
||||
apt-get update
|
||||
apt-get -y install gcc make libtest2-plugin-nowarnings-perl libauthen-radius-perl libconvert-binary-c-perl libcrypt-openssl-rsa-perl libdata-dump-perl libdatetime-format-dateparse-perl libdatetime-format-strptime-perl libdatetime-perl libdbd-mysql-perl libdbd-odbc-perl libdbd-pg-perl libdbd-sybase-perl libdbi-perl libdigest-crc-perl libdigest-md5-perl libdigest-sha-perl libemail-mime-perl libemail-sender-perl libemail-send-smtp-gmail-perl libfilesys-smbclient-perl libhtml-template-perl libio-socket-inet6-perl libio-socket-ip-perl libjmx4perl-perl libjson-maybexs-perl libjson-perl libjson-webtoken-perl libmail-imapclient-perl libmime-base64-perl libmongodb-perl libnet-dhcp-perl libnet-dns-perl libnet-ldap-perl libnet-mqtt-simple-perl libnet-ntp-perl libnet-ssleay-perl libnet-subnet-perl libnet-telnet-perl libnet-tftp-perl libopenwsman-perl libredis-perl librrds-perl libsnmp-perl libsocket-perl libssh-session-perl libtest-www-selenium-perl libtext-csv-perl libtime-hires-perl libtime-parsedate-perl libuuid-perl libxml-libxml-perl libxml-libxml-simple-perl libxml-simple-perl libxml-xpath-perl libzmq-libzmq4-perl perl perl-modules
|
||||
# this image is used by centreon-perl-libs unit test and centreon-gorgone unit tests.
|
||||
apt-get -y install libcrypt-openssl-aes-perl libnet-curl-perl libyaml-libyaml-perl libhash-merge-perl libclone-choose-perl libcryptx-perl libjson-xs-perl libjson-pp-perl
|
||||
apt-get clean
|
||||
NONINTERACTIVE_TESTING=1 PERL_MM_USE_DEFAULT=1 cpan Test2::Harness UUID
|
||||
|
||||
mkdir -p /var/lib/centreon/centplugins/
|
||||
chmod 777 /var/lib/centreon/centplugins/
|
||||
|
||||
EOF
|
8
.github/workflows/as400.yml
vendored
8
.github/workflows/as400.yml
vendored
@ -47,7 +47,9 @@ jobs:
|
||||
- package_extension: deb
|
||||
image: packaging-plugins-java-jammy
|
||||
distrib: jammy
|
||||
|
||||
- package_extension: deb
|
||||
image: packaging-plugins-java-noble
|
||||
distrib: noble
|
||||
|
||||
container:
|
||||
image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/${{ matrix.image }}
|
||||
@ -102,7 +104,7 @@ jobs:
|
||||
stability: ${{ needs.get-environment.outputs.stability }}
|
||||
|
||||
- name: Save to cache
|
||||
uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ./*.${{ matrix.package_extension }}
|
||||
key: ${{ github.sha }}-${{ github.run_id }}-${{ matrix.package_extension }}-${{ matrix.distrib }}
|
||||
@ -130,6 +132,8 @@ jobs:
|
||||
package_extension: deb
|
||||
- distrib: jammy
|
||||
package_extension: deb
|
||||
- distrib: noble
|
||||
package_extension: deb
|
||||
|
||||
name: deliver ${{ matrix.distrib }}
|
||||
steps:
|
||||
|
5
.github/workflows/connector-vmware.yml
vendored
5
.github/workflows/connector-vmware.yml
vendored
@ -48,6 +48,9 @@ jobs:
|
||||
- package_extension: deb
|
||||
image: packaging-plugins-jammy
|
||||
distrib: jammy
|
||||
- package_extension: deb
|
||||
image: packaging-plugins-noble
|
||||
distrib: noble
|
||||
|
||||
container:
|
||||
image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/${{ matrix.image }}
|
||||
@ -106,6 +109,8 @@ jobs:
|
||||
package_extension: deb
|
||||
- distrib: jammy
|
||||
package_extension: deb
|
||||
- distrib: noble
|
||||
package_extension: deb
|
||||
|
||||
name: deliver ${{ matrix.distrib }}
|
||||
steps:
|
||||
|
@ -63,6 +63,12 @@ jobs:
|
||||
- runner: ubuntu-22.04
|
||||
dockerfile: packaging-plugins-java-jammy
|
||||
image: packaging-plugins-java-jammy
|
||||
- runner: ubuntu-22.04
|
||||
dockerfile: packaging-plugins-noble
|
||||
image: packaging-plugins-noble
|
||||
- runner: ubuntu-22.04
|
||||
dockerfile: packaging-plugins-java-noble
|
||||
image: packaging-plugins-java-noble
|
||||
|
||||
runs-on: ${{ matrix.runner }}
|
||||
|
||||
@ -84,9 +90,9 @@ jobs:
|
||||
username: ${{ secrets.HARBOR_CENTREON_PUSH_USERNAME }}
|
||||
password: ${{ secrets.HARBOR_CENTREON_PUSH_TOKEN }}
|
||||
|
||||
- uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
|
||||
- uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
||||
|
||||
- uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
|
||||
- uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
||||
with:
|
||||
file: .github/docker/packaging/Dockerfile.${{ matrix.dockerfile }}
|
||||
context: .
|
||||
|
@ -48,6 +48,10 @@ jobs:
|
||||
- runner: ubuntu-24.04
|
||||
dockerfile: jammy
|
||||
image: jammy
|
||||
- runner: ubuntu-24.04
|
||||
dockerfile: noble
|
||||
image: noble
|
||||
|
||||
|
||||
runs-on: ${{ matrix.runner }}
|
||||
|
||||
@ -69,9 +73,9 @@ jobs:
|
||||
username: ${{ secrets.HARBOR_CENTREON_PUSH_USERNAME }}
|
||||
password: ${{ secrets.HARBOR_CENTREON_PUSH_TOKEN }}
|
||||
|
||||
- uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
|
||||
- uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
||||
|
||||
- uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
|
||||
- uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
||||
with:
|
||||
file: .github/docker/testing/Dockerfile.testing-plugins-${{ matrix.dockerfile }}
|
||||
context: .
|
||||
|
@ -48,6 +48,9 @@ jobs:
|
||||
- runner: ubuntu-22.04
|
||||
dockerfile: jammy
|
||||
image: jammy
|
||||
- runner: ubuntu-22.04
|
||||
dockerfile: noble
|
||||
image: noble
|
||||
|
||||
runs-on: ${{ matrix.runner }}
|
||||
|
||||
@ -69,9 +72,9 @@ jobs:
|
||||
username: ${{ secrets.HARBOR_CENTREON_PUSH_USERNAME }}
|
||||
password: ${{ secrets.HARBOR_CENTREON_PUSH_TOKEN }}
|
||||
|
||||
- uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
|
||||
- uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
||||
|
||||
- uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
|
||||
- uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
||||
with:
|
||||
file: .github/docker/unit-tests/Dockerfile.unit-tests-${{ matrix.dockerfile }}
|
||||
context: .
|
||||
|
39
.github/workflows/get-environment.yml
vendored
39
.github/workflows/get-environment.yml
vendored
@ -134,7 +134,7 @@ jobs:
|
||||
- if: ${{ steps.has_skip_label.outputs.result == 'true' }}
|
||||
name: Get push changes
|
||||
id: get_push_changes
|
||||
uses: tj-actions/changed-files@d6e91a2266cdb9d62096cebf1e8546899c6aa18f # v45.0.6
|
||||
uses: tj-actions/changed-files@2f7c5bfce28377bc069a65ba478de0a74aa0ca32 # v46.0.1
|
||||
with:
|
||||
since_last_remote_commit: true
|
||||
json: true
|
||||
@ -205,7 +205,7 @@ jobs:
|
||||
script: |
|
||||
const getStability = (branchName) => {
|
||||
switch (true) {
|
||||
case /(^develop$)|(^dev-\d{2}\.\d{2}\.x$)|(^prepare-release-cloud.*)/.test(branchName):
|
||||
case /(^develop$)|(^dev-\d{2}\.\d{2}\.x$)/.test(branchName):
|
||||
return 'unstable';
|
||||
case /(^release.+)|(^hotfix.+)/.test(branchName):
|
||||
return 'testing';
|
||||
@ -250,9 +250,44 @@ jobs:
|
||||
with:
|
||||
script: |
|
||||
const { execSync } = require('child_process');
|
||||
const fs = require('fs');
|
||||
let version = '';
|
||||
if ('${{ inputs.version_file }}'.match(/pom\.xml$/)) {
|
||||
version = execSync(`grep -m 1 "<version>.*</version>" ${{ inputs.version_file }} | sed 's/.*<version>\\(.*\\)<\\/version>.*/\\1/'`).toString().trim();
|
||||
|
||||
} else if ('${{ steps.get_stability.outputs.stability }}' === 'stable') {
|
||||
const { owner, repo } = context.repo;
|
||||
|
||||
// Fetch the most recent tag for plugins
|
||||
const { data: tags } = await github.rest.repos.listTags({
|
||||
owner,
|
||||
repo,
|
||||
per_page: 10
|
||||
});
|
||||
|
||||
let latestTag = null;
|
||||
let latestDate = 0;
|
||||
|
||||
// Filter tags matching format plugins-YYYYMMDD
|
||||
for (const tag of tags) {
|
||||
const match = tag.name.match(/^plugins-(\d{8})$/);
|
||||
|
||||
const tagDate = parseInt(match[1], 10);
|
||||
|
||||
// ensure we get the true latest tag and not the most recent created
|
||||
if (tagDate > latestDate) {
|
||||
latestTag = tag.name;
|
||||
latestDate = tagDate;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Most recent tag found: ${latestTag}`)
|
||||
|
||||
// Get current release tag from .version file
|
||||
version = fs.readFileSync('.version.plugins', 'utf8').trim();
|
||||
|
||||
console.log(`Stable version based on .version.plugins file will be: ${version}`)
|
||||
|
||||
} else if ('${{ steps.get_stability.outputs.stability }}' === 'testing') {
|
||||
const branchName = "${{ github.head_ref || github.ref_name }}";
|
||||
const matches = branchName.match(/^(?:release|hotfix)-(\d{8})$/);
|
||||
|
6
.github/workflows/nrpe.yml
vendored
6
.github/workflows/nrpe.yml
vendored
@ -47,6 +47,9 @@ jobs:
|
||||
- package_extension: deb
|
||||
image: packaging-plugins-jammy
|
||||
distrib: jammy
|
||||
- package_extension: deb
|
||||
image: packaging-plugins-noble
|
||||
distrib: noble
|
||||
|
||||
container:
|
||||
image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/${{ matrix.image }}
|
||||
@ -140,6 +143,9 @@ jobs:
|
||||
package_extension: deb
|
||||
- distrib: jammy
|
||||
package_extension: deb
|
||||
- distrib: noble
|
||||
package_extension: deb
|
||||
|
||||
|
||||
name: deliver ${{ matrix.distrib }}
|
||||
steps:
|
||||
|
43
.github/workflows/perl-cpan-libraries.yml
vendored
43
.github/workflows/perl-cpan-libraries.yml
vendored
@ -325,7 +325,7 @@ jobs:
|
||||
|
||||
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
||||
|
||||
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||
- uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9
|
||||
with:
|
||||
name: packages-rpm-${{ matrix.distrib }}
|
||||
path: ./
|
||||
@ -336,7 +336,7 @@ jobs:
|
||||
- run: rpmsign --addsign ./*.rpm
|
||||
shell: bash
|
||||
|
||||
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
- uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ./*.rpm
|
||||
key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
|
||||
@ -351,7 +351,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
image: [packaging-plugins-bullseye, packaging-plugins-bookworm, packaging-plugins-jammy, packaging-plugins-bullseye-arm64]
|
||||
image: [packaging-plugins-bullseye, packaging-plugins-bookworm, packaging-plugins-jammy, packaging-plugins-noble, packaging-plugins-bullseye-arm64]
|
||||
name:
|
||||
[
|
||||
"ARGV::Struct",
|
||||
@ -386,7 +386,7 @@ jobs:
|
||||
include:
|
||||
- runner_name: ubuntu-24.04
|
||||
- arch: amd64
|
||||
- build_names: "bullseye-amd64,bookworm,jammy"
|
||||
- build_names: "bullseye-amd64,bookworm,jammy,noble"
|
||||
- deb_dependencies: ""
|
||||
- deb_provides: ""
|
||||
- version: ""
|
||||
@ -406,6 +406,10 @@ jobs:
|
||||
distrib: jammy
|
||||
package_extension: deb
|
||||
image: packaging-plugins-jammy
|
||||
- build_name: noble
|
||||
distrib: noble
|
||||
package_extension: deb
|
||||
image: packaging-plugins-noble
|
||||
- build_name: bullseye-arm64
|
||||
distrib: bullseye
|
||||
package_extension: deb
|
||||
@ -413,7 +417,7 @@ jobs:
|
||||
arch: arm64
|
||||
runner_name: centreon-collect-arm64
|
||||
- name: "Crypt::Argon2"
|
||||
build_names: "bullseye-amd64,jammy,bullseye-arm64"
|
||||
build_names: "bullseye-amd64,jammy,noble,bullseye-arm64"
|
||||
preinstall_cpanlibs: "Dist::Build"
|
||||
use_dh_make_perl: "false"
|
||||
no-auto-depends: "true"
|
||||
@ -424,25 +428,25 @@ jobs:
|
||||
use_dh_make_perl: "false"
|
||||
deb_dependencies: "libexporter-tiny-perl libxs-install-perl"
|
||||
no-auto-depends: "true"
|
||||
build_names: "bullseye-amd64,bookworm,jammy,bullseye-arm64"
|
||||
build_names: "bullseye-amd64,bookworm,jammy,noble,bullseye-arm64"
|
||||
- name: "Device::Modbus::RTU::Client"
|
||||
build_names: "bookworm"
|
||||
- name: "Device::Modbus::TCP::Client"
|
||||
build_names: "bookworm"
|
||||
- name: "Digest::SHA1"
|
||||
build_names: "jammy"
|
||||
build_names: "jammy,noble"
|
||||
- name: "Libssh::Session"
|
||||
use_dh_make_perl: "false"
|
||||
build_names: "bullseye-amd64,bookworm,jammy,bullseye-arm64"
|
||||
build_names: "bullseye-amd64,bookworm,jammy,noble,bullseye-arm64"
|
||||
no-auto-depends: "true"
|
||||
deb_dependencies: "libcarp-assert-perl libdynaloader-functions-perl libexporter-tiny-perl libdevel-overloadinfo-perl libssh-4 libc6"
|
||||
deb_provides: "libssh-session-perl-dbgsym libssh-session-sftp"
|
||||
revision: "2"
|
||||
- name: "Net::Amazon::Signature::V4"
|
||||
build_names: ["bullseye-amd64", "jammy"]
|
||||
build_names: ["bullseye-amd64", "jammy", "noble"]
|
||||
- name: "Net::Curl"
|
||||
use_dh_make_perl: "false"
|
||||
build_names: "bullseye-amd64,bookworm,jammy,bullseye-arm64"
|
||||
build_names: "bullseye-amd64,bookworm,jammy,noble,bullseye-arm64"
|
||||
no-auto-depends: "true"
|
||||
deb_dependencies: "libcarp-assert-perl libdynaloader-functions-perl libexporter-tiny-perl libdevel-overloadinfo-perl libcurl4"
|
||||
deb_provides: "libnet-curl-perl-dbgsym libnet-curl-compat-perl libnet-curl-easy-perl libnet-curl-form-perl libnet-curl-share-perl libnet-curl-multi-perl"
|
||||
@ -460,7 +464,7 @@ jobs:
|
||||
use_dh_make_perl: "false"
|
||||
version: "0.01"
|
||||
deb_dependencies: "libzmq5"
|
||||
build_names: "bullseye-amd64,bookworm,jammy,bullseye-arm64"
|
||||
build_names: "bullseye-amd64,bookworm,jammy,noble,bullseye-arm64"
|
||||
name: package ${{ matrix.distrib }} ${{ matrix.arch }} ${{ matrix.name }}
|
||||
container:
|
||||
image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/${{ matrix.image }}:latest
|
||||
@ -572,7 +576,8 @@ jobs:
|
||||
fi
|
||||
|
||||
# Check deb
|
||||
dpkg-deb --contents $created_package || { echo "Error: dpkg-deb failed for package $created_package"; exit 1; }
|
||||
dpkg-deb --verbose --contents $created_package || { echo "Error: dpkg-deb failed for package $created_package"; exit 1; }
|
||||
|
||||
shell: bash
|
||||
|
||||
- if: ${{ steps.check-package-existence.outputs.do_not_build == 'false' && contains(matrix.build_names, matrix.build_name) && matrix.use_dh_make_perl == 'true' }}
|
||||
@ -617,7 +622,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
matrix:
|
||||
distrib: [bullseye, bookworm, jammy]
|
||||
distrib: [bullseye, bookworm, jammy, noble]
|
||||
|
||||
steps:
|
||||
- name: Merge Artifacts
|
||||
@ -642,14 +647,14 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
matrix:
|
||||
distrib: [bullseye, bookworm, jammy]
|
||||
distrib: [bullseye, bookworm, jammy, noble]
|
||||
steps:
|
||||
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||
- uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9
|
||||
with:
|
||||
name: packages-deb-${{ matrix.distrib }}
|
||||
path: ./
|
||||
|
||||
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
- uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ./*.deb
|
||||
key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }}
|
||||
@ -685,6 +690,10 @@ jobs:
|
||||
distrib: jammy
|
||||
arch: amd64
|
||||
runner_name: ubuntu-24.04
|
||||
- package_extension: deb
|
||||
image: ubuntu:noble
|
||||
arch: amd64
|
||||
runner_name: ubuntu-24.04
|
||||
- package_extension: deb
|
||||
image: debian:bullseye
|
||||
distrib: bullseye
|
||||
@ -737,6 +746,8 @@ jobs:
|
||||
package_extension: deb
|
||||
- distrib: jammy
|
||||
package_extension: deb
|
||||
- distrib: noble
|
||||
package_extension: deb
|
||||
|
||||
name: deliver ${{ matrix.distrib }}
|
||||
steps:
|
||||
|
13
.github/workflows/perl-filesys-smbclient.yml
vendored
13
.github/workflows/perl-filesys-smbclient.yml
vendored
@ -63,7 +63,7 @@ jobs:
|
||||
cp -r ~/rpmbuild/RPMS/x86_64/*.rpm .
|
||||
shell: bash
|
||||
|
||||
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
- uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ./*.rpm
|
||||
key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
|
||||
@ -97,7 +97,7 @@ jobs:
|
||||
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
- uses: actions/cache/restore@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ./*.rpm
|
||||
key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
|
||||
@ -108,7 +108,7 @@ jobs:
|
||||
- run: rpmsign --addsign ./*.rpm
|
||||
shell: bash
|
||||
|
||||
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
- uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ./*.rpm
|
||||
key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
|
||||
@ -129,6 +129,9 @@ jobs:
|
||||
distrib: bookworm
|
||||
- image: packaging-plugins-jammy
|
||||
distrib: jammy
|
||||
- image: packaging-plugins-noble
|
||||
distrib: noble
|
||||
|
||||
name: package ${{ matrix.distrib }}
|
||||
container:
|
||||
image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/${{ matrix.image }}:latest
|
||||
@ -155,7 +158,7 @@ jobs:
|
||||
DEB_BUILD_OPTIONS="nocheck nodocs notest noautodbgsym" dh-make-perl make --dist ${{ matrix.distrib }} --verbose --build --version 4.0${{ steps.parse-distrib.outputs.package_distrib_separator }}${{ steps.parse-distrib.outputs.package_distrib_name }} perl-filesys-smbclient/
|
||||
shell: bash
|
||||
|
||||
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
- uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ./*.deb
|
||||
key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }}
|
||||
@ -183,6 +186,8 @@ jobs:
|
||||
package_extension: deb
|
||||
- distrib: jammy
|
||||
package_extension: deb
|
||||
- distrib: noble
|
||||
package_extension: deb
|
||||
|
||||
name: deliver ${{ matrix.distrib }}
|
||||
steps:
|
||||
|
5
.github/workflows/perl-keepass-reader.yml
vendored
5
.github/workflows/perl-keepass-reader.yml
vendored
@ -50,6 +50,9 @@ jobs:
|
||||
- image: packaging-plugins-jammy
|
||||
distrib: jammy
|
||||
package_extension: deb
|
||||
- image: packaging-plugins-noble
|
||||
distrib: noble
|
||||
package_extension: deb
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
@ -142,6 +145,8 @@ jobs:
|
||||
package_extension: deb
|
||||
- distrib: jammy
|
||||
package_extension: deb
|
||||
- distrib: noble
|
||||
package_extension: deb
|
||||
|
||||
name: deliver ${{ matrix.distrib }}
|
||||
steps:
|
||||
|
11
.github/workflows/perl-openwsman.yml
vendored
11
.github/workflows/perl-openwsman.yml
vendored
@ -55,6 +55,11 @@ jobs:
|
||||
package_extension: deb
|
||||
runner: ubuntu-22.04
|
||||
arch: amd64
|
||||
- image: packaging-plugins-noble
|
||||
distrib: noble
|
||||
package_extension: deb
|
||||
runner: ubuntu-22.04
|
||||
arch: amd64
|
||||
- image: packaging-plugins-bullseye-arm64
|
||||
distrib: bullseye
|
||||
package_extension: deb
|
||||
@ -208,7 +213,7 @@ jobs:
|
||||
rpm_gpg_signing_passphrase: ${{ secrets.RPM_GPG_SIGNING_PASSPHRASE }}
|
||||
stability: ${{ needs.get-environment.outputs.stability }}
|
||||
|
||||
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
- uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ./*.${{ matrix.package_extension }}
|
||||
key: cache-${{ github.sha }}-${{ matrix.package_extension }}-wsman-${{ matrix.distrib }}-${{ matrix.arch }}-${{ github.head_ref || github.ref_name }}
|
||||
@ -244,6 +249,10 @@ jobs:
|
||||
- distrib: jammy
|
||||
package_extension: deb
|
||||
arch: amd64
|
||||
- distrib: noble
|
||||
package_extension: deb
|
||||
arch: amd64
|
||||
|
||||
|
||||
name: deliver ${{ matrix.distrib }} ${{ matrix.arch }}
|
||||
steps:
|
||||
|
9
.github/workflows/perl-vmware-vsphere.yml
vendored
9
.github/workflows/perl-vmware-vsphere.yml
vendored
@ -43,7 +43,7 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
- name: Cache vsphere cli sources
|
||||
uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: vmware-vsphere-cli-distrib
|
||||
key: ${{ github.sha }}-${{ github.run_id }}-sources-perl-vmware-vsphere
|
||||
@ -82,6 +82,11 @@ jobs:
|
||||
distrib: jammy
|
||||
runner: ubuntu-22.04
|
||||
arch: amd64
|
||||
- package_extension: deb
|
||||
image: packaging-plugins-noble
|
||||
distrib: noble
|
||||
runner: ubuntu-22.04
|
||||
arch: amd64
|
||||
- package_extension: deb
|
||||
image: packaging-plugins-bullseye-arm64
|
||||
distrib: bullseye
|
||||
@ -103,7 +108,7 @@ jobs:
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Import source files
|
||||
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
uses: actions/cache/restore@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: vmware-vsphere-cli-distrib
|
||||
key: ${{ github.sha }}-${{ github.run_id }}-sources-perl-vmware-vsphere
|
||||
|
6
.github/workflows/plink.yml
vendored
6
.github/workflows/plink.yml
vendored
@ -57,7 +57,7 @@ jobs:
|
||||
cp -r ~/rpmbuild/RPMS/x86_64/*.rpm .
|
||||
shell: bash
|
||||
|
||||
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
- uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ./*.rpm
|
||||
key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
|
||||
@ -91,7 +91,7 @@ jobs:
|
||||
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
- uses: actions/cache/restore@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ./*.rpm
|
||||
key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
|
||||
@ -102,7 +102,7 @@ jobs:
|
||||
- run: rpmsign --addsign ./*.rpm
|
||||
shell: bash
|
||||
|
||||
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
- uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ./*.rpm
|
||||
key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
|
||||
|
21
.github/workflows/plugins.yml
vendored
21
.github/workflows/plugins.yml
vendored
@ -98,7 +98,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
image: [unit-tests-alma8, unit-tests-alma9, unit-tests-bullseye, unit-tests-bullseye-arm64, unit-tests-bookworm, unit-tests-jammy]
|
||||
image: [unit-tests-alma8, unit-tests-alma9, unit-tests-bullseye, unit-tests-bullseye-arm64, unit-tests-bookworm, unit-tests-jammy, unit-tests-noble]
|
||||
include:
|
||||
- runner_name: ubuntu-24.04
|
||||
- package_extension: rpm
|
||||
@ -120,6 +120,9 @@ jobs:
|
||||
- package_extension: deb
|
||||
image: unit-tests-jammy
|
||||
distrib: jammy
|
||||
- package_extension: deb
|
||||
image: unit-tests-noble
|
||||
distrib: noble
|
||||
|
||||
runs-on: ${{ matrix.runner_name }}
|
||||
container:
|
||||
@ -168,7 +171,7 @@ jobs:
|
||||
COMMIT=$(git log -1 HEAD --pretty=format:%h)
|
||||
perl .github/scripts/plugins-source.container.pl "${{ needs.get-plugins.outputs.plugins }}" "${{ needs.get-environment.outputs.version }} ($COMMIT)"
|
||||
|
||||
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
- uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ./build/
|
||||
key: fatpacked-plugins-${{ github.sha }}-${{ github.run_id }}
|
||||
@ -206,6 +209,9 @@ jobs:
|
||||
- package_extension: deb
|
||||
image: packaging-plugins-jammy
|
||||
distrib: jammy
|
||||
- package_extension: deb
|
||||
image: packaging-plugins-noble
|
||||
distrib: noble
|
||||
|
||||
container:
|
||||
image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/${{ matrix.image }}
|
||||
@ -219,7 +225,7 @@ jobs:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
- uses: actions/cache/restore@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ./build/
|
||||
key: fatpacked-plugins-${{ github.sha }}-${{ github.run_id }}
|
||||
@ -311,7 +317,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
image: [testing-plugins-alma8, testing-plugins-alma9, testing-plugins-jammy, testing-plugins-bullseye, testing-plugins-bookworm]
|
||||
image: [testing-plugins-alma8, testing-plugins-alma9, testing-plugins-jammy, testing-plugins-bullseye, testing-plugins-bookworm, testing-plugins-noble, testing-plugins-bullseye-arm64]
|
||||
include:
|
||||
- runner_name: ubuntu-24.04
|
||||
- package_extension: rpm
|
||||
@ -329,6 +335,9 @@ jobs:
|
||||
- package_extension: deb
|
||||
image: testing-plugins-jammy
|
||||
distrib: jammy
|
||||
- package_extension: deb
|
||||
image: testing-plugins-noble
|
||||
distrib: noble
|
||||
- package_extension: deb
|
||||
image: testing-plugins-bullseye-arm64
|
||||
distrib: bullseye
|
||||
@ -385,6 +394,8 @@ jobs:
|
||||
package_extension: deb
|
||||
- distrib: jammy
|
||||
package_extension: deb
|
||||
- distrib: noble
|
||||
package_extension: deb
|
||||
|
||||
name: deliver ${{ matrix.distrib }}
|
||||
steps:
|
||||
@ -412,7 +423,7 @@ jobs:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
|
||||
- uses: actions/cache/restore@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
|
||||
with:
|
||||
path: ./build/
|
||||
key: fatpacked-plugins-${{ github.sha }}-${{ github.run_id }}
|
||||
|
19
.gitleaks.toml
Normal file
19
.gitleaks.toml
Normal file
@ -0,0 +1,19 @@
|
||||
title = "Gitleaks custom rules"
|
||||
|
||||
[extend]
|
||||
useDefault = true
|
||||
|
||||
[allowlist]
|
||||
paths = [
|
||||
'''vendor\/''',
|
||||
'''(.*?)\.rptlibrary''',
|
||||
'''pnpm-lock\.yaml''',
|
||||
'''\.gitleaks\.toml$''',
|
||||
'''(.*?)(jpg|gif|doc|pdf|bin)$'''
|
||||
]
|
||||
|
||||
regexTarget = "match"
|
||||
regexes = [
|
||||
'''ABCDEFG1234567890''',
|
||||
'''s\.aBCD123DEF456GHI789JKL012'''
|
||||
]
|
1
.version.plugins
Normal file
1
.version.plugins
Normal file
@ -0,0 +1 @@
|
||||
20250303
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
"dependencies": [
|
||||
]
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"pkg_name": "centreon-plugin-Applications-Exense-Step-Restapi",
|
||||
"pkg_summary": "Centreon Plugin",
|
||||
"plugin_name": "centreon_exense_step_restapi.pl",
|
||||
"files": [
|
||||
"centreon/plugins/script_custom.pm",
|
||||
"apps/exense/step/restapi/"
|
||||
]
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": [
|
||||
"perl(DateTime)"
|
||||
]
|
||||
}
|
4
packaging/centreon-plugin-Notification-Foxbox/deb.json
Normal file
4
packaging/centreon-plugin-Notification-Foxbox/deb.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"dependencies": [
|
||||
]
|
||||
}
|
9
packaging/centreon-plugin-Notification-Foxbox/pkg.json
Normal file
9
packaging/centreon-plugin-Notification-Foxbox/pkg.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"pkg_name": "centreon-plugin-Notification-Foxbox",
|
||||
"pkg_summary": "Centreon Plugin to send notifications by Foxbox",
|
||||
"plugin_name": "centreon_notification_foxbox.pl",
|
||||
"files": [
|
||||
"centreon/plugins/script_simple.pm",
|
||||
"notification/foxbox"
|
||||
]
|
||||
}
|
4
packaging/centreon-plugin-Notification-Foxbox/rpm.json
Normal file
4
packaging/centreon-plugin-Notification-Foxbox/rpm.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"dependencies": [
|
||||
]
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": [
|
||||
"liburi-encode-perl"
|
||||
]
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"pkg_name": "centreon-plugin-Notification-Jasminsms-Httpapi",
|
||||
"pkg_summary": "Centreon Plugin to send notifications by Jasmin SMS HTTP-API",
|
||||
"plugin_name": "centreon_notification_jasminsms-httpapi.pl",
|
||||
"files": [
|
||||
"centreon/plugins/script_custom.pm",
|
||||
"notification/jasminsms/httpapi"
|
||||
]
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": [
|
||||
"perl(URI::Encode)"
|
||||
]
|
||||
}
|
5
packaging/centreon-plugin-Notification-Ovhsms/deb.json
Normal file
5
packaging/centreon-plugin-Notification-Ovhsms/deb.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": [
|
||||
"libjson-perl"
|
||||
]
|
||||
}
|
9
packaging/centreon-plugin-Notification-Ovhsms/pkg.json
Normal file
9
packaging/centreon-plugin-Notification-Ovhsms/pkg.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"pkg_name": "centreon-plugin-Notification-Ovhsms",
|
||||
"pkg_summary": "Centreon Plugin to send notifications by OVH SMS API",
|
||||
"plugin_name": "centreon_notification_ovhsms.pl",
|
||||
"files": [
|
||||
"centreon/plugins/script_simple.pm",
|
||||
"notification/ovhsms"
|
||||
]
|
||||
}
|
5
packaging/centreon-plugin-Notification-Ovhsms/rpm.json
Normal file
5
packaging/centreon-plugin-Notification-Ovhsms/rpm.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": [
|
||||
"perl(JSON::XS)"
|
||||
]
|
||||
}
|
5
packaging/centreon-plugin-Notification-Telegram/deb.json
Normal file
5
packaging/centreon-plugin-Notification-Telegram/deb.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": [
|
||||
"libjson-perl"
|
||||
]
|
||||
}
|
9
packaging/centreon-plugin-Notification-Telegram/pkg.json
Normal file
9
packaging/centreon-plugin-Notification-Telegram/pkg.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"pkg_name": "centreon-plugin-Notification-Telegram",
|
||||
"pkg_summary": "Centreon Plugin to send notifications by Telegram",
|
||||
"plugin_name": "centreon_notification_telegram.pl",
|
||||
"files": [
|
||||
"centreon/plugins/script_simple.pm",
|
||||
"notification/telegram"
|
||||
]
|
||||
}
|
5
packaging/centreon-plugin-Notification-Telegram/rpm.json
Normal file
5
packaging/centreon-plugin-Notification-Telegram/rpm.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": [
|
||||
"perl(JSON::XS)"
|
||||
]
|
||||
}
|
@ -310,11 +310,11 @@ Filter job type (can be a regexp).
|
||||
|
||||
=item B<--filter-start-time>
|
||||
|
||||
Filter job with start time greater than current time less value in seconds.
|
||||
Tolerance value in seconds, to avoid skipping jobs whose start time is earlier than the current time.
|
||||
|
||||
=item B<--filter-end-time>
|
||||
|
||||
Filter job with end time greater than current time less value in seconds (default: 86400).
|
||||
Tolerance value in seconds, to avoid skipping jobs whose end time is earlier than the current time (default: 86400).
|
||||
|
||||
=item B<--ok-status>
|
||||
|
||||
|
@ -251,6 +251,7 @@ sub cache_backup_job_session {
|
||||
return $datas;
|
||||
}
|
||||
|
||||
|
||||
sub cache_repository {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
@ -281,6 +282,24 @@ sub get_backup_job_session {
|
||||
);
|
||||
}
|
||||
|
||||
sub get_replica_job_session {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return $self->get_cache_file_response(statefile => 'replica_job_session')
|
||||
if (defined($self->{option_results}->{cache_use}) && !defined($options{disable_cache}));
|
||||
|
||||
my $creation_time = DateTime->now->subtract(seconds => $options{timeframe})->iso8601();
|
||||
|
||||
return $self->request_api(
|
||||
endpoint => '/api/query',
|
||||
get_param => [
|
||||
'type=ReplicaJobSession',
|
||||
'format=Entities',
|
||||
'filter=CreationTime>=' . $creation_time
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
sub get_repository {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
|
@ -229,6 +229,7 @@ sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $jobs_exec = $options{custom}->get_backup_job_session(timeframe => $self->{option_results}->{timeframe});
|
||||
my $jobs_replica = $options{custom}->get_replica_job_session(timeframe => $self->{option_results}->{timeframe});
|
||||
|
||||
my $ctime = time();
|
||||
|
||||
@ -278,6 +279,50 @@ sub manage_selection {
|
||||
$self->{jobs}->{ $job->{JobUid} }->{failed}->{failed}++;
|
||||
}
|
||||
}
|
||||
foreach my $job (@{$jobs_replica->{Entities}->{ReplicaJobSessions}->{ReplicaJobSessions}}) {
|
||||
next if (defined($self->{option_results}->{filter_uid}) && $self->{option_results}->{filter_uid} ne '' && $job->{JobUid} !~ /$self->{option_results}->{filter_uid}/);
|
||||
next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && $job->{JobName} !~ /$self->{option_results}->{filter_name}/);
|
||||
next if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '' && $job->{JobType} !~ /$self->{option_results}->{filter_type}/);
|
||||
|
||||
if (!defined($self->{jobs}->{ $job->{JobUid} })) {
|
||||
$self->{jobs}->{ $job->{JobUid} } = {
|
||||
name => $job->{JobName},
|
||||
type => $job->{JobType},
|
||||
failed => { name => $job->{JobName}, total => 0, failed => 0 }
|
||||
};
|
||||
$self->{global}->{detected}++;
|
||||
}
|
||||
|
||||
$job->{CreationTimeUTC} =~ /^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)/;
|
||||
my $dt = DateTime->new(year => $1, month => $2, day => $3, hour => $4, minute => $5, second => $6);
|
||||
my $epoch = $dt->epoch();
|
||||
|
||||
if (!defined($self->{jobs}->{ $job->{JobUid} }->{executions}) || $epoch > $self->{jobs}->{ $job->{JobUid} }->{executions}->{last}->{epoch}) {
|
||||
$self->{jobs}->{ $job->{JobUid} }->{executions}->{last} = {
|
||||
jobName => $job->{JobName},
|
||||
started => $job->{CreationTimeUTC},
|
||||
status => $job->{Result},
|
||||
epoch => $epoch
|
||||
};
|
||||
|
||||
$self->{jobs}->{ $job->{JobUid} }->{timers} = {
|
||||
name => $job->{JobName},
|
||||
lastExecSeconds => $ctime - $epoch,
|
||||
lastExecHuman => centreon::plugins::misc::change_seconds(value => $ctime - $epoch)
|
||||
};
|
||||
|
||||
if ($job->{State} =~ /Starting|Working|Resuming/i) {
|
||||
my $duration = $ctime - $epoch;
|
||||
$self->{jobs}->{ $job->{JobUid} }->{timers}->{durationSeconds} = $duration;
|
||||
$self->{jobs}->{ $job->{JobUid} }->{timers}->{durationHuman} = centreon::plugins::misc::change_seconds(value => $duration);
|
||||
}
|
||||
}
|
||||
|
||||
$self->{jobs}->{ $job->{JobUid} }->{failed}->{total}++;
|
||||
if (defined($job->{Result}) && $job->{Result} =~ /Failed/i) {
|
||||
$self->{jobs}->{ $job->{JobUid} }->{failed}->{failed}++;
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $uid (keys %{$self->{jobs}}) {
|
||||
$self->{jobs}->{$uid}->{failed}->{failedPrct} = $self->{jobs}->{$uid}->{failed}->{total} > 0 ? $self->{jobs}->{$uid}->{failed}->{failed} * 100 / $self->{jobs}->{$uid}->{failed}->{total} : 0;
|
||||
@ -308,7 +353,7 @@ Filter jobs by type.
|
||||
|
||||
=item B<--timeframe>
|
||||
|
||||
Timeframe to get BackupJobSession (in seconds. Default: 86400).
|
||||
Timeframe to get BackupJobSession and ReplicaJobSession (in seconds. Default: 86400).
|
||||
|
||||
=item B<--unit>
|
||||
|
||||
|
@ -51,6 +51,8 @@ sub manage_selection {
|
||||
|
||||
my $results = {};
|
||||
my $jobs_exec = $options{custom}->cache_backup_job_session(timeframe => $self->{option_results}->{timeframe});
|
||||
my $jobs_replica = $options{custom}->get_replica_job_session(timeframe => $self->{option_results}->{timeframe});
|
||||
|
||||
foreach my $job (@{$jobs_exec->{Entities}->{BackupJobSessions}->{BackupJobSessions}}) {
|
||||
next if (defined($results->{ $job->{JobUid} }));
|
||||
|
||||
@ -60,6 +62,15 @@ sub manage_selection {
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $job (@{$jobs_replica->{Entities}->{ReplicaJobSessions}->{ReplicaJobSessions}}) {
|
||||
next if (defined($results->{ $job->{JobUid} }));
|
||||
|
||||
$results->{ $job->{JobUid} } = {
|
||||
jobName => $job->{JobName},
|
||||
jobType => $job->{JobType}
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
@ -67,7 +78,7 @@ sub run {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $results = $self->manage_selection(%options);
|
||||
foreach my $uid (keys %$results) {
|
||||
foreach my $uid (sort keys %$results) {
|
||||
$self->{output}->output_add(
|
||||
long_msg => sprintf(
|
||||
'[uid: %s][jobName: %s][jobType: %s]',
|
||||
@ -117,7 +128,7 @@ List jobs.
|
||||
|
||||
=item B<--timeframe>
|
||||
|
||||
Timeframe to get BackupJobSession (in seconds. Default: 86400).
|
||||
Timeframe to get BackupJobSession and ReplicaJobSession (in seconds. Default: 86400).
|
||||
|
||||
=back
|
||||
|
||||
|
@ -38,7 +38,7 @@ sub set_counters {
|
||||
{ label => 'clients-' . $label,
|
||||
nlabel => 'clients.' . $label . '.count',
|
||||
set => {
|
||||
key_values => [{ name => $label }],
|
||||
key_values => [ { name => $label } ],
|
||||
output_template => ucfirst($label) . ' clients: %d',
|
||||
perfdatas => [
|
||||
{ label => $label . '_clients', template => '%d',
|
||||
@ -51,7 +51,7 @@ sub set_counters {
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
bless $self, $class;
|
||||
|
||||
return $self;
|
||||
@ -62,7 +62,7 @@ sub manage_selection {
|
||||
|
||||
my %results = $options{mqtt}->queries(
|
||||
base_topic => '$SYS/broker/clients/',
|
||||
topics => ['connected', 'maximum', 'active', 'inactive']
|
||||
topics => [ 'connected', 'maximum', 'active', 'inactive' ]
|
||||
);
|
||||
|
||||
for my $topic (keys %results) {
|
||||
@ -80,10 +80,37 @@ Check clients statistics.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
=item B<--warning-clients-connected>
|
||||
|
||||
Thresholds.
|
||||
Can be: 'clients-connected', 'clients-maximum', 'clients-active', 'clients-inactive'.
|
||||
Warning threshold for connected clients.
|
||||
|
||||
=item B<--critical-clients-connected>
|
||||
|
||||
Critical threshold for connected clients.
|
||||
|
||||
=item B<--warning-clients-maximum>
|
||||
|
||||
Warning threshold for maximum clients.
|
||||
|
||||
=item B<--critical-clients-maximum>
|
||||
|
||||
Critical threshold for maximum clients.
|
||||
|
||||
=item B<--warning-clients-active>
|
||||
|
||||
Warning threshold for active clients.
|
||||
|
||||
=item B<--critical-clients-active>
|
||||
|
||||
Critical threshold for active clients.
|
||||
|
||||
=item B<--warning-clients-inactive>
|
||||
|
||||
Warning threshold for inactive clients.
|
||||
|
||||
=item B<--critical-clients-inactive>
|
||||
|
||||
Critical threshold for inactive clients.
|
||||
|
||||
=back
|
||||
|
||||
|
@ -38,7 +38,7 @@ sub set_counters {
|
||||
{ label => 'messages-' . $label,
|
||||
nlabel => 'messages.' . $label . '.count',
|
||||
set => {
|
||||
key_values => [{ name => $label }],
|
||||
key_values => [ { name => $label } ],
|
||||
output_template => ucfirst($label) . ' messages: %d',
|
||||
perfdatas => [
|
||||
{ label => $label . '_messages', template => '%d',
|
||||
@ -51,7 +51,7 @@ sub set_counters {
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
bless $self, $class;
|
||||
|
||||
return $self;
|
||||
@ -62,7 +62,7 @@ sub manage_selection {
|
||||
|
||||
my %results = $options{mqtt}->queries(
|
||||
base_topic => '$SYS/broker/messages/',
|
||||
topics => ['stored', 'received', 'sent']
|
||||
topics => [ 'stored', 'received', 'sent' ]
|
||||
);
|
||||
for my $topic (keys %results) {
|
||||
$self->{global}->{$topic} = $results{$topic};
|
||||
@ -79,10 +79,29 @@ Check messages statistics.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
=item B<--warning-messages-stored>
|
||||
|
||||
Thresholds.
|
||||
Can be: 'messages-stored', 'messages-received', 'messages-sent'.
|
||||
Warning threshold for stored messages.
|
||||
|
||||
=item B<--critical-messages-stored>
|
||||
|
||||
Critical threshold for stored messages.
|
||||
|
||||
=item B<--warning-messages-received>
|
||||
|
||||
Warning threshold for received messages.
|
||||
|
||||
=item B<--critical-messages-received>
|
||||
|
||||
Critical threshold for received messages.
|
||||
|
||||
=item B<--warning-messages-sent>
|
||||
|
||||
Warning threshold for sent messages.
|
||||
|
||||
=item B<--critical-messages-sent>
|
||||
|
||||
Critical threshold for sent messages.
|
||||
|
||||
=back
|
||||
|
||||
|
@ -30,13 +30,13 @@ use POSIX qw(floor);
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
'topic:s' => { name => 'topic' },
|
||||
'warning:s' => { name => 'warning' },
|
||||
'critical:s' => { name => 'critical' },
|
||||
'warning:s' => { name => 'warning', redirect => 'warning-generic' },
|
||||
'critical:s' => { name => 'critical', redirect => 'critical-generic' },
|
||||
'extracted-pattern:s' => { name => 'extracted_pattern' },
|
||||
'format:s' => { name => 'format' },
|
||||
'format-custom:s' => { name => 'format_custom' },
|
||||
@ -57,25 +57,20 @@ sub custom_generic_output {
|
||||
$format = $self->{instance_mode}{option_results}->{format};
|
||||
}
|
||||
|
||||
my $value = $self->{result_values}->{numericvalue};
|
||||
if (!centreon::plugins::misc::is_empty($self->{instance_mode}{option_results}->{format_custom})) {
|
||||
$value = eval "$value $self->{instance_mode}{option_results}->{format_custom}";
|
||||
}
|
||||
|
||||
return sprintf($format, $value);
|
||||
return sprintf($format, $self->{result_values}->{numericvalue});
|
||||
}
|
||||
|
||||
sub custom_generic_perfdata {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{output}->perfdata_add(
|
||||
label => $options{option_results}->{perfdata_name},
|
||||
unit => $options{option_results}->{perfdata_unit},
|
||||
label => $self->{instance_mode}->{option_results}->{perfdata_name},
|
||||
unit => $self->{instance_mode}->{option_results}->{perfdata_unit},
|
||||
value => $self->{result_values}->{numericvalue},
|
||||
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
|
||||
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
|
||||
min => $options{option_results}->{perfdata_min},
|
||||
max => $options{option_results}->{perfdata_max}
|
||||
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-generic'),
|
||||
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-generic'),
|
||||
min => $self->{instance_mode}->{option_results}->{perfdata_min},
|
||||
max => $self->{instance_mode}->{option_results}->{perfdata_max}
|
||||
);
|
||||
}
|
||||
|
||||
@ -85,9 +80,9 @@ sub custom_generic_threshold {
|
||||
return $self->{perfdata}->threshold_check(
|
||||
value => $self->{result_values}->{numericvalue},
|
||||
threshold => [
|
||||
{ label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' },
|
||||
{ label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' },
|
||||
{ label => 'unknown-' . $self->{thlabel}, exit_litteral => 'unknown' }
|
||||
{ label => 'critical-generic', exit_litteral => 'critical' },
|
||||
{ label => 'warning-generic', exit_litteral => 'warning' },
|
||||
{ label => 'unknown-generic', exit_litteral => 'unknown' }
|
||||
]
|
||||
);
|
||||
}
|
||||
@ -102,7 +97,7 @@ sub set_counters {
|
||||
$self->{maps_counters}->{global} = [
|
||||
{ label => 'generic',
|
||||
set => {
|
||||
key_values => [{ name => 'numericvalue' }],
|
||||
key_values => [ { name => 'numericvalue' } ],
|
||||
closure_custom_output => $self->can('custom_generic_output'),
|
||||
closure_custom_perfdata => $self->can('custom_generic_perfdata'),
|
||||
closure_custom_threshold_check => $self->can('custom_generic_threshold')
|
||||
@ -146,6 +141,10 @@ sub manage_selection {
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
if (!centreon::plugins::misc::is_empty($self->{option_results}->{format_custom})) {
|
||||
$value = eval "$value $self->{option_results}->{format_custom}";
|
||||
}
|
||||
|
||||
$self->{global} = { numericvalue => $value };
|
||||
}
|
||||
|
||||
@ -177,7 +176,7 @@ Define a pattern to extract a number from the returned string.
|
||||
|
||||
=item B<--format>
|
||||
|
||||
Output format (default: 'current value is %s')
|
||||
Output format (default: 'current value is %s').
|
||||
|
||||
=item B<--format-custom>
|
||||
|
||||
@ -186,19 +185,19 @@ Apply a custom change on the value
|
||||
|
||||
=item B<--perfdata-unit>
|
||||
|
||||
Perfdata unit in perfdata output (default: '')
|
||||
Perfdata unit in perfdata output (default: '').
|
||||
|
||||
=item B<--perfdata-name>
|
||||
|
||||
Perfdata name in perfdata output (default: 'value')
|
||||
Perfdata name in perfdata output (default: 'value').
|
||||
|
||||
=item B<--perfdata-min>
|
||||
|
||||
Minimum value to add in perfdata output (default: '')
|
||||
Minimum value to add in perfdata output (default: '').
|
||||
|
||||
=item B<--perfdata-max>
|
||||
|
||||
Maximum value to add in perfdata output (default: '')
|
||||
Maximum value to add in perfdata output (default: '').
|
||||
|
||||
=back
|
||||
|
||||
|
@ -28,7 +28,7 @@ use centreon::plugins::misc;
|
||||
use Time::HiRes qw(time);
|
||||
use POSIX qw(floor);
|
||||
|
||||
my $unitdiv = { s => 1, w => 604800, d => 86400, h => 3600, m => 60 };
|
||||
my $unitdiv = { s => 1, w => 604800, d => 86400, h => 3600, m => 60 };
|
||||
my $unitdiv_long = { s => 'seconds', w => 'weeks', d => 'days', h => 'hours', m => 'minutes' };
|
||||
|
||||
sub custom_uptime_output {
|
||||
@ -76,7 +76,7 @@ sub set_counters {
|
||||
$self->{maps_counters}->{global} = [
|
||||
{ label => 'uptime',
|
||||
set => {
|
||||
key_values => [{ name => 'uptime' }],
|
||||
key_values => [ { name => 'uptime' } ],
|
||||
closure_custom_output => $self->can('custom_uptime_output'),
|
||||
closure_custom_perfdata => $self->can('custom_uptime_perfdata'),
|
||||
closure_custom_threshold_check => $self->can('custom_uptime_threshold')
|
||||
@ -87,7 +87,7 @@ sub set_counters {
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
@ -109,7 +109,7 @@ sub check_options {
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $topic = '$SYS/broker/uptime';
|
||||
my $topic = '$SYS/broker/uptime';
|
||||
my $uptime = $options{mqtt}->query(
|
||||
topic => $topic
|
||||
);
|
||||
|
319
src/apps/exense/step/restapi/custom/api.pm
Normal file
319
src/apps/exense/step/restapi/custom/api.pm
Normal file
@ -0,0 +1,319 @@
|
||||
#
|
||||
# Copyright 2025 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
# service performance.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
package apps::exense::step::restapi::custom::api;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use centreon::plugins::http;
|
||||
use centreon::plugins::statefile;
|
||||
use JSON::XS;
|
||||
use Digest::MD5 qw(md5_hex);
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = {};
|
||||
bless $self, $class;
|
||||
|
||||
if (!defined($options{output})) {
|
||||
print "Class Custom: Need to specify 'output' argument.\n";
|
||||
exit 3;
|
||||
}
|
||||
if (!defined($options{options})) {
|
||||
$options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument.");
|
||||
$options{output}->option_exit();
|
||||
}
|
||||
|
||||
if (!defined($options{noptions})) {
|
||||
$options{options}->add_options(arguments => {
|
||||
'hostname:s' => { name => 'hostname' },
|
||||
'port:s' => { name => 'port' },
|
||||
'proto:s' => { name => 'proto' },
|
||||
'api-username:s' => { name => 'api_username' },
|
||||
'api-password:s' => { name => 'api_password' },
|
||||
'token:s' => { name => 'token' },
|
||||
'timeout:s' => { name => 'timeout' }
|
||||
});
|
||||
}
|
||||
$options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1);
|
||||
|
||||
$self->{output} = $options{output};
|
||||
$self->{http} = centreon::plugins::http->new(%options, default_backend => 'curl');
|
||||
$self->{cache_connect} = centreon::plugins::statefile->new(%options);
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub set_options {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{option_results} = $options{option_results};
|
||||
}
|
||||
|
||||
sub set_defaults {}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : '';
|
||||
$self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https';
|
||||
$self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 443;
|
||||
$self->{api_username} = (defined($self->{option_results}->{api_username})) ? $self->{option_results}->{api_username} : '';
|
||||
$self->{api_password} = (defined($self->{option_results}->{api_password})) ? $self->{option_results}->{api_password} : '';
|
||||
$self->{token} = (defined($self->{option_results}->{token})) ? $self->{option_results}->{token} : '';
|
||||
$self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 30;
|
||||
$self->{unknown_http_status} = (defined($self->{option_results}->{unknown_http_status})) ? $self->{option_results}->{unknown_http_status} : '%{http_code} < 200 or %{http_code} >= 300' ;
|
||||
$self->{warning_http_status} = (defined($self->{option_results}->{warning_http_status})) ? $self->{option_results}->{warning_http_status} : '';
|
||||
$self->{critical_http_status} = (defined($self->{option_results}->{critical_http_status})) ? $self->{option_results}->{critical_http_status} : '';
|
||||
|
||||
if ($self->{hostname} eq '') {
|
||||
$self->{output}->add_option_msg(short_msg => 'Need to specify hostname option.');
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
if ($self->{token} ne '') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($self->{api_username} eq '') {
|
||||
$self->{output}->add_option_msg(short_msg => "Need to specify --api-username or --token option.");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
if ($self->{api_password} eq '') {
|
||||
$self->{output}->add_option_msg(short_msg => "Need to specify --api-password option.");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
$self->{cache_connect}->check_options(option_results => $self->{option_results});
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub get_connection_infos {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return $self->{hostname} . '_' . $self->{http}->get_port();
|
||||
}
|
||||
|
||||
sub get_hostname {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return $self->{hostname};
|
||||
}
|
||||
|
||||
sub get_port {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return $self->{port};
|
||||
}
|
||||
|
||||
|
||||
sub build_options_for_httplib {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{option_results}->{hostname} = $self->{hostname};
|
||||
$self->{option_results}->{port} = $self->{port};
|
||||
$self->{option_results}->{proto} = $self->{proto};
|
||||
}
|
||||
|
||||
sub settings {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->build_options_for_httplib();
|
||||
$self->{http}->add_header(key => 'Accept', value => 'application/json');
|
||||
$self->{http}->add_header(key => 'Content-Type', value => 'application/json');
|
||||
$self->{http}->set_options(%{$self->{option_results}});
|
||||
}
|
||||
|
||||
sub clean_session_id {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $datas = { updated => time() };
|
||||
$self->{cache_connect}->write(data => $datas);
|
||||
}
|
||||
|
||||
sub get_session_id {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $has_cache_file = $self->{cache_connect}->read(statefile => 'exense_step_' . md5_hex($self->{option_results}->{hostname}) . '_' . md5_hex($self->{option_results}->{api_username}));
|
||||
my $session_id = $self->{cache_connect}->get(name => 'session_id');
|
||||
my $md5_secret_cache = $self->{cache_connect}->get(name => 'md5_secret');
|
||||
my $md5_secret = md5_hex($self->{api_username} . $self->{api_password});
|
||||
|
||||
if ($has_cache_file == 0 ||
|
||||
!defined($session_id) ||
|
||||
(defined($md5_secret_cache) && $md5_secret_cache ne $md5_secret)
|
||||
) {
|
||||
my $json_request = { username => $self->{api_username}, password => $self->{api_password} };
|
||||
my $encoded = centreon::plugins::misc::json_encode($json_request);
|
||||
unless($encoded) {
|
||||
$self->{output}->add_option_msg(short_msg => 'cannot encode json request');
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
my ($content) = $self->{http}->request(
|
||||
method => 'POST',
|
||||
url_path => '/rest/access/login',
|
||||
query_form_post => $encoded,
|
||||
warning_status => '', unknown_status => '', critical_status => ''
|
||||
);
|
||||
|
||||
if ($self->{http}->get_code() != 200) {
|
||||
$self->{output}->add_option_msg(short_msg => "Authentication error [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
my (@cookies) = $self->{http}->get_first_header(name => 'Set-Cookie');
|
||||
foreach my $cookie (@cookies) {
|
||||
$session_id = $1 if ($cookie =~ /sessionid=(.+?);/);
|
||||
}
|
||||
|
||||
if (!defined($session_id)) {
|
||||
$self->{output}->add_option_msg(short_msg => "Cannot get cookie");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
my $datas = {
|
||||
updated => time(),
|
||||
session_id => $session_id,
|
||||
md5_secret => $md5_secret
|
||||
};
|
||||
$self->{cache_connect}->write(data => $datas);
|
||||
}
|
||||
|
||||
return $session_id;
|
||||
}
|
||||
|
||||
sub credentials {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $creds = {};
|
||||
if ($self->{token} ne '') {
|
||||
$creds = {
|
||||
header => ['Authorization: Bearer ' . $self->{token}],
|
||||
unknown_status => $self->{unknown_http_status},
|
||||
warning_status => $self->{warning_http_status},
|
||||
critical_status => $self->{critical_http_status}
|
||||
};
|
||||
} else {
|
||||
my $session_id = $self->get_session_id();
|
||||
$creds = {
|
||||
header => ['Cookie: sessionid=' . $session_id],
|
||||
warning_status => '',
|
||||
unknown_status => '',
|
||||
critical_status => ''
|
||||
};
|
||||
}
|
||||
|
||||
return $creds;
|
||||
}
|
||||
|
||||
sub request {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $endpoint = $options{endpoint};
|
||||
|
||||
$self->settings();
|
||||
my $creds = $self->credentials();
|
||||
|
||||
my $content = $self->{http}->request(
|
||||
method => $options{method},
|
||||
url_path => $endpoint,
|
||||
get_param => $options{get_param},
|
||||
query_form_post => $options{query_form_post},
|
||||
%$creds
|
||||
);
|
||||
|
||||
# Maybe there is an issue with the token. So we retry.
|
||||
if ($self->{http}->get_code() < 200 || $self->{http}->get_code() >= 300) {
|
||||
$self->clean_session_id();
|
||||
$creds = $self->credentials();
|
||||
$creds->{unknown_status} = $self->{unknown_http_status};
|
||||
$creds->{warning_status} = $self->{warning_status};
|
||||
$creds->{critical_http_status} = $self->{critical_http_status};
|
||||
$content = $self->{http}->request(
|
||||
method => $options{method},
|
||||
url_path => $endpoint,
|
||||
get_param => $options{get_param},
|
||||
query_form_post => $options{query_form_post},
|
||||
%$creds
|
||||
);
|
||||
}
|
||||
|
||||
return if (defined($options{skip_decode}));
|
||||
|
||||
my $decoded = centreon::plugins::misc::json_decode($content);
|
||||
if (!defined($decoded)) {
|
||||
$self->{output}->add_option_msg(short_msg => 'Error while retrieving data (add --debug option for detailed message)');
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Exense Step API
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
Exense Step API
|
||||
|
||||
=head1 REST API OPTIONS
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--hostname>
|
||||
|
||||
API hostname.
|
||||
|
||||
=item B<--port>
|
||||
|
||||
API port (default: 443)
|
||||
|
||||
=item B<--proto>
|
||||
|
||||
Specify https if needed (default: 'https')
|
||||
|
||||
=item B<--token>
|
||||
|
||||
Use token authentication.
|
||||
|
||||
=item B<--api-username>
|
||||
|
||||
Set API username
|
||||
|
||||
=item B<--api-password>
|
||||
|
||||
Set API password
|
||||
|
||||
=item B<--timeout>
|
||||
|
||||
Set HTTP timeout
|
||||
|
||||
=back
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<custom>.
|
||||
|
||||
=cut
|
147
src/apps/exense/step/restapi/mode/listplans.pm
Normal file
147
src/apps/exense/step/restapi/mode/listplans.pm
Normal file
@ -0,0 +1,147 @@
|
||||
#
|
||||
# Copyright 2025 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
# service performance.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
package apps::exense::step::restapi::mode::listplans;
|
||||
|
||||
use base qw(centreon::plugins::mode);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use JSON::XS;
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
'tenant-name:s' => { name => 'tenant_name' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::init(%options);
|
||||
|
||||
if (!defined($self->{option_results}->{tenant_name}) || $self->{option_results}->{tenant_name} eq '') {
|
||||
$self->{option_results}->{tenant_name} = '[All]';
|
||||
}
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $payload = $self->{option_results}->{tenant_name};
|
||||
$options{custom}->request(method => 'POST', endpoint => '/rest/tenants/current', query_form_post => $payload, skip_decode => 1);
|
||||
|
||||
$payload = {
|
||||
skip => 0,
|
||||
limit => 4000000,
|
||||
filters => [
|
||||
{
|
||||
collectionFilter => { type => 'True', field => 'visible' }
|
||||
}
|
||||
],
|
||||
'sort' => {
|
||||
'field' => 'attributes.name',
|
||||
'direction' => 'ASCENDING'
|
||||
}
|
||||
};
|
||||
$payload = centreon::plugins::misc::json_encode($payload);
|
||||
unless($payload) {
|
||||
$self->{output}->add_option_msg(short_msg => 'cannot encode json request');
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
my $plans = $options{custom}->request(method => 'POST', endpoint => '/rest/table/plans', query_form_post => $payload);
|
||||
|
||||
my $results = [];
|
||||
foreach my $plan (@{$plans->{data}}) {
|
||||
# skip plans created by keyword single execution
|
||||
next if ($plan->{visible} =~ /false|0/);
|
||||
|
||||
push @$results, {
|
||||
id => $plan->{id},
|
||||
name => $plan->{attributes}->{name}
|
||||
};
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
sub run {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $results = $self->manage_selection(%options);
|
||||
foreach (@$results) {
|
||||
$self->{output}->output_add(
|
||||
long_msg => sprintf(
|
||||
'[id: %s][name: %s]',
|
||||
$_->{id},
|
||||
$_->{name}
|
||||
)
|
||||
);
|
||||
}
|
||||
$self->{output}->output_add(
|
||||
severity => 'OK',
|
||||
short_msg => 'List plans:'
|
||||
);
|
||||
|
||||
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
|
||||
$self->{output}->exit();
|
||||
}
|
||||
|
||||
sub disco_format {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{output}->add_disco_format(elements => ['id', 'name']);
|
||||
}
|
||||
|
||||
sub disco_show {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $results = $self->manage_selection(%options);
|
||||
foreach (@$results) {
|
||||
$self->{output}->add_disco_entry(
|
||||
id => $_->{id},
|
||||
name => $_->{name}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
List plans.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--tenant-name>
|
||||
|
||||
Check plan of a tenant (default: '[All]').
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
111
src/apps/exense/step/restapi/mode/listtenants.pm
Normal file
111
src/apps/exense/step/restapi/mode/listtenants.pm
Normal file
@ -0,0 +1,111 @@
|
||||
#
|
||||
# Copyright 2025 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
# service performance.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
package apps::exense::step::restapi::mode::listtenants;
|
||||
|
||||
use base qw(centreon::plugins::mode);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use JSON::XS;
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::init(%options);
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $tenants = $options{custom}->request(method => 'GET', endpoint => '/rest/tenants');
|
||||
|
||||
my $results = [];
|
||||
foreach my $tenant (@$tenants) {
|
||||
push @$results, {
|
||||
name => $tenant->{name},
|
||||
projectId => defined($tenant->{projectId}) ? $tenant->{projectId} : '',
|
||||
global => $tenant->{global} =~ /true|1/i ? 1 : 0
|
||||
};
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
sub run {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $results = $self->manage_selection(%options);
|
||||
foreach (@$results) {
|
||||
$self->{output}->output_add(
|
||||
long_msg => sprintf(
|
||||
'[name: %s][projectId: %s][global: %s]',
|
||||
$_->{name},
|
||||
$_->{projectId},
|
||||
$_->{global}
|
||||
)
|
||||
);
|
||||
}
|
||||
$self->{output}->output_add(
|
||||
severity => 'OK',
|
||||
short_msg => 'List tenants:'
|
||||
);
|
||||
|
||||
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
|
||||
$self->{output}->exit();
|
||||
}
|
||||
|
||||
sub disco_format {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{output}->add_disco_format(elements => ['name', 'projectId', 'global']);
|
||||
}
|
||||
|
||||
sub disco_show {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $results = $self->manage_selection(%options);
|
||||
foreach (@$results) {
|
||||
$self->{output}->add_disco_entry(%$_);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
List tenants.
|
||||
|
||||
=over 8
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
507
src/apps/exense/step/restapi/mode/plans.pm
Normal file
507
src/apps/exense/step/restapi/mode/plans.pm
Normal file
@ -0,0 +1,507 @@
|
||||
#
|
||||
# Copyright 2025 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
# service performance.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
package apps::exense::step::restapi::mode::plans;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use DateTime;
|
||||
use POSIX;
|
||||
use JSON::XS;
|
||||
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
|
||||
use centreon::plugins::misc;
|
||||
|
||||
my $unitdiv = { s => 1, w => 604800, d => 86400, h => 3600, m => 60 };
|
||||
my $unitdiv_long = { s => 'seconds', w => 'weeks', d => 'days', h => 'hours', m => 'minutes' };
|
||||
|
||||
sub custom_last_exec_perfdata {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{output}->perfdata_add(
|
||||
nlabel => $self->{nlabel} . '.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{unit} },
|
||||
instances => $self->{result_values}->{name},
|
||||
unit => $self->{instance_mode}->{option_results}->{unit},
|
||||
value => $self->{result_values}->{lastExecSeconds} >= 0 ? floor($self->{result_values}->{lastExecSeconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }) : $self->{result_values}->{lastExecSeconds},
|
||||
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
|
||||
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
|
||||
min => 0
|
||||
);
|
||||
}
|
||||
|
||||
sub custom_last_exec_threshold {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return $self->{perfdata}->threshold_check(
|
||||
value => $self->{result_values}->{lastExecSeconds} >= 0 ? floor($self->{result_values}->{lastExecSeconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }) : $self->{result_values}->{lastExecSeconds},
|
||||
threshold => [
|
||||
{ label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' },
|
||||
{ label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' },
|
||||
{ label => 'unknown-'. $self->{thlabel}, exit_litteral => 'unknown' }
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
sub custom_duration_perfdata {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{output}->perfdata_add(
|
||||
nlabel => $self->{nlabel} . '.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{unit} },
|
||||
instances => $self->{result_values}->{name},
|
||||
unit => $self->{instance_mode}->{option_results}->{unit},
|
||||
value => floor($self->{result_values}->{durationSeconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }),
|
||||
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
|
||||
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
|
||||
min => 0
|
||||
);
|
||||
}
|
||||
|
||||
sub custom_duration_threshold {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return $self->{perfdata}->threshold_check(
|
||||
value => floor($self->{result_values}->{durationSeconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }),
|
||||
threshold => [
|
||||
{ label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' },
|
||||
{ label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' },
|
||||
{ label => 'unknown-'. $self->{thlabel}, exit_litteral => 'unknown' }
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
sub custom_execution_status_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return sprintf(
|
||||
"result: %s, status: %s",
|
||||
$self->{result_values}->{result},
|
||||
$self->{result_values}->{status}
|
||||
);
|
||||
}
|
||||
|
||||
sub plan_long_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return sprintf(
|
||||
"checking plan '%s'",
|
||||
$options{instance_value}->{name}
|
||||
);
|
||||
}
|
||||
|
||||
sub prefix_plan_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $plan_name = defined $options{instance_value}->{name} ? $options{instance_value}->{name} : 'unknown';
|
||||
|
||||
return sprintf("plan '%s' ", $plan_name);
|
||||
}
|
||||
|
||||
sub prefix_global_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return 'Number of plans ';
|
||||
}
|
||||
|
||||
sub prefix_execution_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return sprintf(
|
||||
"execution '%s' [env: %s] [started: %s] ",
|
||||
$options{instance_value}->{executionId},
|
||||
$options{instance_value}->{environment},
|
||||
$options{instance_value}->{started}
|
||||
);
|
||||
}
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{ name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' },
|
||||
{ name => 'plans', type => 3, cb_prefix_output => 'prefix_plan_output', cb_long_output => 'prefix_plan_output', indent_long_output => ' ', message_multiple => 'All plans are ok',
|
||||
group => [
|
||||
{ name => 'exec_detect', type => 0 },
|
||||
{ name => 'failed', type => 0 },
|
||||
{ name => 'timers', type => 0, skipped_code => { -10 => 1 } },
|
||||
{ name => 'executions', type => 1, cb_prefix_output => 'prefix_execution_output', message_multiple => 'executions are ok', display_long => 1, sort_method => 'num', skipped_code => { -10 => 1 } }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{global} = [
|
||||
{ label => 'plans-detected', display_ok => 0, nlabel => 'plans.detected.count', set => {
|
||||
key_values => [ { name => 'detected' } ],
|
||||
output_template => 'detected: %s',
|
||||
perfdatas => [
|
||||
{ template => '%s', min => 0 }
|
||||
]
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{exec_detect} = [
|
||||
{ label => 'plan-executions-detected', nlabel => 'plan.executions.detected.count', set => {
|
||||
key_values => [ { name => 'detected' }, { name => 'name' } ],
|
||||
output_template => 'number of plan executions detected: %s',
|
||||
perfdatas => [
|
||||
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'name' }
|
||||
]
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{failed} = [
|
||||
{ label => 'plan-executions-failed-prct', nlabel => 'plan.executions.failed.percentage', set => {
|
||||
key_values => [ { name => 'failedPrct' }, { name => 'name' } ],
|
||||
output_template => 'number of failed executions: %.2f %%',
|
||||
perfdatas => [
|
||||
{ template => '%.2f', unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'name' }
|
||||
]
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{timers} = [
|
||||
{ label => 'plan-execution-last', nlabel => 'plan.execution.last', set => {
|
||||
key_values => [ { name => 'lastExecSeconds' }, { name => 'lastExecHuman' }, { name => 'name' } ],
|
||||
output_template => 'last execution %s',
|
||||
output_use => 'lastExecHuman',
|
||||
closure_custom_perfdata => $self->can('custom_last_exec_perfdata'),
|
||||
closure_custom_threshold_check => $self->can('custom_last_exec_threshold')
|
||||
}
|
||||
},
|
||||
{ label => 'plan-running-duration', nlabel => 'plan.running.duration', set => {
|
||||
key_values => [ { name => 'durationSeconds' }, { name => 'durationHuman' }, { name => 'name' } ],
|
||||
output_template => 'running duration %s',
|
||||
output_use => 'durationHuman',
|
||||
closure_custom_perfdata => $self->can('custom_duration_perfdata'),
|
||||
closure_custom_threshold_check => $self->can('custom_duration_threshold')
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{executions} = [
|
||||
{
|
||||
label => 'plan-execution-status',
|
||||
type => 2,
|
||||
set => {
|
||||
key_values => [
|
||||
{ name => 'status' }, {name => 'result' }, { name => 'planName' }
|
||||
],
|
||||
closure_custom_output => $self->can('custom_execution_status_output'),
|
||||
closure_custom_perfdata => sub { return 0; },
|
||||
closure_custom_threshold_check => \&catalog_status_threshold_ng
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
'filter-plan-id:s' => { name => 'filter_plan_id' },
|
||||
'filter-plan-name:s' => { name => 'filter_plan_name' },
|
||||
'filter-environment:s' => { name => 'filter_environment' },
|
||||
'since-timeperiod:s' => { name => 'since_timeperiod' },
|
||||
'status-failed:s' => { name => 'status_failed' },
|
||||
'only-last-execution' => { name => 'only_last_execution' },
|
||||
'tenant-name:s' => { name => 'tenant_name' },
|
||||
'timezone:s' => { name => 'timezone' },
|
||||
'unit:s' => { name => 'unit', default => 's' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
if ($self->{option_results}->{unit} eq '' || !defined($unitdiv->{$self->{option_results}->{unit}})) {
|
||||
$self->{option_results}->{unit} = 's';
|
||||
}
|
||||
|
||||
if (!defined($self->{option_results}->{since_timeperiod}) || $self->{option_results}->{since_timeperiod} eq '') {
|
||||
$self->{option_results}->{since_timeperiod} = 86400;
|
||||
}
|
||||
|
||||
if (!defined($self->{option_results}->{tenant_name}) || $self->{option_results}->{tenant_name} eq '') {
|
||||
$self->{option_results}->{tenant_name} = '[All]';
|
||||
}
|
||||
|
||||
$self->{tz} = {};
|
||||
if (defined($self->{option_results}->{timezone}) && $self->{option_results}->{timezone} ne '') {
|
||||
$self->{tz} = centreon::plugins::misc::set_timezone(name => $self->{option_results}->{timezone});
|
||||
}
|
||||
|
||||
$self->{option_results}->{timezone} = 'UTC' if (!defined($self->{option_results}->{timezone}) || $self->{option_results}->{timezone}
|
||||
eq '');
|
||||
|
||||
if (!defined($self->{option_results}->{status_failed}) || $self->{option_results}->{status_failed} eq '') {
|
||||
$self->{option_results}->{status_failed} = '%{result} =~ /technical_error|failed|interrupted/i';
|
||||
}
|
||||
|
||||
$self->{option_results}->{status_failed} =~ s/%\{(.*?)\}/\$values->{$1}/g;
|
||||
$self->{option_results}->{status_failed} =~ s/%\((.*?)\)/\$values->{$1}/g;
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $status_filter = {};
|
||||
if (defined($self->{option_results}->{filter_status}) && $self->{option_results}->{filter_status}[0] ne '') {
|
||||
$status_filter->{statusFilter} = $self->{option_results}->{filter_status};
|
||||
}
|
||||
|
||||
my $payload = $self->{option_results}->{tenant_name};
|
||||
$options{custom}->request(method => 'POST', endpoint => '/rest/tenants/current', query_form_post => $payload, skip_decode => 1);
|
||||
|
||||
$payload = {
|
||||
skip => 0,
|
||||
limit => 4000000,
|
||||
filters => [
|
||||
{
|
||||
collectionFilter => { type => 'True', field => 'visible' }
|
||||
}
|
||||
],
|
||||
'sort' => {
|
||||
'field' => 'attributes.name',
|
||||
'direction' => 'ASCENDING'
|
||||
}
|
||||
};
|
||||
eval {
|
||||
$payload = encode_json($payload);
|
||||
};
|
||||
if ($@) {
|
||||
$self->{output}->add_option_msg(short_msg => 'cannot encode json request');
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
my $plans = $options{custom}->request(method => 'POST', endpoint => '/rest/table/plans', query_form_post => $payload);
|
||||
|
||||
my $ctime = time();
|
||||
my $filterTime = ($ctime - $self->{option_results}->{since_timeperiod}) * 1000;
|
||||
|
||||
$payload = {
|
||||
skip => 0,
|
||||
limit => 4000000,
|
||||
filters => [
|
||||
{
|
||||
collectionFilter => { type => 'Gte', field => 'startTime', value => $filterTime }
|
||||
}
|
||||
],
|
||||
'sort' => {
|
||||
'field' => 'startTime',
|
||||
'direction' => 'DESCENDING'
|
||||
}
|
||||
};
|
||||
eval {
|
||||
$payload = encode_json($payload);
|
||||
};
|
||||
if ($@) {
|
||||
$self->{output}->add_option_msg(short_msg => 'cannot encode json request');
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
my $executions = $options{custom}->request(method => 'POST', endpoint => '/rest/table/executions', query_form_post => $payload);
|
||||
|
||||
$self->{global} = { detected => 0 };
|
||||
$self->{plans} = {};
|
||||
foreach my $plan (@{$plans->{data}}) {
|
||||
# skip plans created by keyword single execution
|
||||
next if (defined $plan->{visible} && $plan->{visible} =~ /false|0/);
|
||||
next if (defined($self->{option_results}->{filter_plan_id}) && $self->{option_results}->{filter_plan_id} ne '' &&
|
||||
$plan->{id} !~ /$self->{option_results}->{filter_plan_id}/);
|
||||
next if (defined($self->{option_results}->{filter_plan_name}) && $self->{option_results}->{filter_plan_name} ne '' &&
|
||||
$plan->{attributes}->{name} !~ /$self->{option_results}->{filter_plan_name}/);
|
||||
|
||||
$self->{global}->{detected}++;
|
||||
|
||||
$self->{plans}->{ $plan->{id} } = {
|
||||
name => $plan->{attributes}->{name},
|
||||
exec_detect => { detected => 0, name => $plan->{attributes}->{name} },
|
||||
failed => { failedPrct => 0, name => $plan->{attributes}->{name} },
|
||||
timers => {},
|
||||
executions => {}
|
||||
};
|
||||
|
||||
my ($last_exec, $older_running_exec);
|
||||
my ($failed, $total) = (0, 0);
|
||||
my $i = 0;
|
||||
foreach my $plan_exec (@{$executions->{data}}) {
|
||||
next if (!defined($plan_exec->{planId}));
|
||||
next if ($plan_exec->{planId} ne $plan->{id});
|
||||
$plan_exec->{startTimeSec} = $plan_exec->{startTime} / 1000;
|
||||
next if ($plan_exec->{startTimeSec} < ($ctime - $self->{option_results}->{since_timeperiod}));
|
||||
next if (defined($self->{option_results}->{filter_environment}) && $self->{option_results}->{filter_environment} ne '' &&
|
||||
$plan_exec->{executionParameters}->{customParameters}->{env} !~ /$self->{option_results}->{filter_environment}/);
|
||||
|
||||
# if the endTime is empty, we store this older running execution for later
|
||||
if (!defined($plan_exec->{endTime}) || $plan_exec->{endTime} eq '') {
|
||||
$older_running_exec = $plan_exec;
|
||||
}
|
||||
if (!defined($last_exec)) {
|
||||
$last_exec = $plan_exec;
|
||||
}
|
||||
|
||||
$self->{plans}->{ $plan->{id} }->{exec_detect}->{detected}++;
|
||||
$failed++ if ($self->{output}->test_eval(test => $self->{option_results}->{status_failed}, values => { result => lc($plan_exec->{result}), status => lc($plan_exec->{status}) }));
|
||||
$total++;
|
||||
|
||||
my $dt = DateTime->from_epoch(epoch => $plan_exec->{startTimeSec}, %{$self->{tz}});
|
||||
my $timeraised = sprintf(
|
||||
'%02d-%02d-%02dT%02d:%02d:%02d (%s)', $dt->year, $dt->month, $dt->day, $dt->hour, $dt->minute, $dt->second, $self->{option_results}->{timezone}
|
||||
);
|
||||
$self->{plans}->{ $plan->{id} }->{executions}->{$i} = {
|
||||
executionId => $plan_exec->{id},
|
||||
planName => $plan->{attributes}->{name},
|
||||
environment => $plan_exec->{executionParameters}->{customParameters}->{env},
|
||||
started => $timeraised,
|
||||
status => lc($plan_exec->{status}),
|
||||
result => lc($plan_exec->{result})
|
||||
};
|
||||
$i++;
|
||||
|
||||
last if (defined($self->{option_results}->{only_last_execution}));
|
||||
}
|
||||
|
||||
$self->{plans}->{ $plan->{id} }->{failed}->{failedPrct} = $total > 0 ? $failed * 100 / $total : 0;
|
||||
|
||||
if (defined($last_exec)) {
|
||||
$self->{plans}->{ $plan->{id} }->{timers} = {
|
||||
name => $plan->{attributes}->{name},
|
||||
lastExecSeconds => defined($last_exec->{startTime}) ? $ctime - $last_exec->{startTimeSec} : -1,
|
||||
lastExecHuman => defined($last_exec->{startTime}) ? centreon::plugins::misc::change_seconds(value => $ctime - $last_exec->{startTimeSec}) : 'never'
|
||||
};
|
||||
}
|
||||
|
||||
if (defined($older_running_exec)) {
|
||||
my $duration = $ctime - $older_running_exec->{startTime};
|
||||
$self->{plans}->{ $plan->{name} }->{timers}->{durationSeconds} = $duration;
|
||||
$self->{plans}->{ $plan->{name} }->{timers}->{durationHuman} = centreon::plugins::misc::change_seconds(value => $duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check plans.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--tenant-name>
|
||||
|
||||
Check plan of a tenant (default: '[All]').
|
||||
|
||||
=item B<--filter-plan-id>
|
||||
|
||||
Filter plans by plan ID.
|
||||
|
||||
=item B<--filter-plan-name>
|
||||
|
||||
Filter plans by plan name.
|
||||
|
||||
=item B<--filter-environment>
|
||||
|
||||
Filter plan executions by environment name.
|
||||
|
||||
=item B<--since-timeperiod>
|
||||
|
||||
Time period to get plans executions information (in seconds. default: 86400).
|
||||
|
||||
=item B<--only-last-execution>
|
||||
|
||||
Check only last plan execution.
|
||||
|
||||
=item B<--timezone>
|
||||
|
||||
Define timezone for start/end plan execution time (default is 'UTC').
|
||||
|
||||
=item B<--status-failed>
|
||||
|
||||
Expression to define status failed (default: '%{result} =~ /technical_error|failed|interrupted/i').
|
||||
|
||||
=item B<--unknown-plan-execution-status>
|
||||
|
||||
Set unknown threshold for last plan execution status.
|
||||
You can use the following variables: %{status}, %{planName}
|
||||
|
||||
=item B<--warning-plan-execution-status>
|
||||
|
||||
Set warning threshold for last plan execution status.
|
||||
You can use the following variables: %{status}, %{planName}
|
||||
|
||||
=item B<--critical-plan-execution-status>
|
||||
|
||||
Set critical threshold for last plan execution status.
|
||||
You can use the following variables: %{status}, %{planName}
|
||||
|
||||
=item B<--warning-plans-detected>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-plans-detected>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-plan-executions-detected>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-plan-executions-detected>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-plan-executions-failed-prct>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-plan-executions-failed-prct>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-plan-execution-last>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-plan-execution-last>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-plan-running-duration>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-plan-running-duration>
|
||||
|
||||
Thresholds.
|
||||
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
51
src/apps/exense/step/restapi/plugin.pm
Normal file
51
src/apps/exense/step/restapi/plugin.pm
Normal file
@ -0,0 +1,51 @@
|
||||
#
|
||||
# Copyright 2025 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
# service performance.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
package apps::exense::step::restapi::plugin;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base qw(centreon::plugins::script_custom);
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
bless $self, $class;
|
||||
|
||||
$self->{modes} = {
|
||||
'list-plans' => 'apps::exense::step::restapi::mode::listplans',
|
||||
'list-tenants' => 'apps::exense::step::restapi::mode::listtenants',
|
||||
'plans' => 'apps::exense::step::restapi::mode::plans'
|
||||
};
|
||||
|
||||
$self->{custom_modes}->{api} = 'apps::exense::step::restapi::custom::api';
|
||||
return $self;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 PLUGIN DESCRIPTION
|
||||
|
||||
Check Exense Step using Rest API.
|
||||
|
||||
=cut
|
@ -53,7 +53,16 @@ sub set_counters {
|
||||
{ name => 'scenarios', type => 3, cb_prefix_output => 'prefix_scenario_output', cb_long_output => 'prefix_scenario_output', indent_long_output => ' ', message_multiple => 'All scenarios are ok',
|
||||
group => [
|
||||
{ name => 'global', type => 0, skipped_code => { -10 => 1 } },
|
||||
{ name => 'steps', display_long => 1, cb_prefix_output => 'prefix_steps_output', message_multiple => 'All steps are ok', type => 1, skipped_code => { -10 => 1 } }
|
||||
{
|
||||
name => 'steps',
|
||||
type => 1,
|
||||
cb_prefix_output => 'prefix_steps_output',
|
||||
display_long => 1,
|
||||
message_multiple => 'All steps are ok',
|
||||
skipped_code => { -10 => 1 },
|
||||
sort_method => 'num',
|
||||
sort_attribute => 'index'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
@ -98,7 +107,7 @@ sub set_counters {
|
||||
];
|
||||
$self->{maps_counters}->{steps} = [
|
||||
{ label => 'time-step', nlabel => 'scenario.step.time.milliseconds', set => {
|
||||
key_values => [ { name => 'time_step' }, { name => 'display' }, { name => 'last_exec' } ],
|
||||
key_values => [ { name => 'time_step' }, { name => 'display' }, { name => 'last_exec' }, { name => 'index' } ],
|
||||
output_template => 'time step: %s ms',
|
||||
perfdatas => [
|
||||
{ template => '%s', unit => 'ms', min => 0, label_extra_instance => 1 }
|
||||
@ -106,7 +115,7 @@ sub set_counters {
|
||||
}
|
||||
},
|
||||
{ label => 'time-total', nlabel => 'scenario.steps.time.total.milliseconds', set => {
|
||||
key_values => [ { name => 'time_total' }, { name => 'display' }, { name => 'last_exec' } ],
|
||||
key_values => [ { name => 'time_total' }, { name => 'display' }, { name => 'last_exec' }, { name => 'index' } ],
|
||||
output_template => 'time total: %s ms',
|
||||
perfdatas => [
|
||||
{ template => '%s', unit => 'ms', min => 0, label_extra_instance => 1 }
|
||||
@ -209,6 +218,7 @@ sub manage_selection {
|
||||
$self->{scenarios}->{ $scenario->{scenarioName} }->{steps}->{ $self->{scenarios}->{ $scenario->{scenarioName} }->{steps_index}->{ $step_metrics->{stepId} } }->{ $step_metrics->{metric} } = $step_metrics->{value};
|
||||
$self->{scenarios}->{ $scenario->{scenarioName} }->{steps}->{ $self->{scenarios}->{ $scenario->{scenarioName} }->{steps_index}->{ $step_metrics->{stepId} } }->{last_exec} = POSIX::strftime('%d-%m-%Y %H:%M:%S %Z', localtime($exec_time));
|
||||
$self->{scenarios}->{ $scenario->{scenarioName} }->{steps}->{ $self->{scenarios}->{ $scenario->{scenarioName} }->{steps_index}->{ $step_metrics->{stepId} } }->{display} = $self->{scenarios}->{ $scenario->{scenarioName} }->{steps_index}->{ $step_metrics->{stepId} };
|
||||
$self->{scenarios}->{ $scenario->{scenarioName} }->{steps}->{ $self->{scenarios}->{ $scenario->{scenarioName} }->{steps_index}->{ $step_metrics->{stepId} } }->{index} = $step_metrics->{stepId};
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,14 +264,53 @@ Syntax: C<--warning-scenario-status='%{status} =~ "xxx"'>
|
||||
Critical threshold for scenario status (default: '%{status} =~ "Failure"').
|
||||
Syntax: --critical-scenario-status='%{status} =~ "xxx"'
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
=item B<--warning-availability>
|
||||
|
||||
Thresholds.
|
||||
Common: 'availability' (%),
|
||||
For WEB scenarios: 'time-total-allsteps' (ms), 'time-step' (ms),
|
||||
For HTTPR scenarios: 'time-total' (ms),
|
||||
FOR BPL scenarios: 'time-interaction' (ms), 'time-total' (ms).
|
||||
Thresholds in %.
|
||||
|
||||
=item B<--critical-availability>
|
||||
|
||||
Thresholds in %.
|
||||
|
||||
=item B<--warning-time-total-allsteps>
|
||||
|
||||
Thresholds in ms for WEB scenarios.
|
||||
|
||||
=item B<--critical-time-total-allsteps>
|
||||
|
||||
Thresholds in ms for WEB scenarios.
|
||||
|
||||
=item B<--warning-time-step>
|
||||
|
||||
Thresholds in ms for WEB scenarios.
|
||||
|
||||
=item B<--critical-time-step>
|
||||
|
||||
Thresholds in ms for WEB scenarios.
|
||||
|
||||
=item B<--warning-time-total>
|
||||
|
||||
Thresholds in ms for HTTPR scenarios.
|
||||
|
||||
=item B<--critical-time-total>
|
||||
|
||||
Thresholds in ms for HTTPR scenarios.
|
||||
|
||||
=item B<--warning-time-interaction>
|
||||
|
||||
Thresholds in ms for BPL scenarios.
|
||||
|
||||
=item B<--critical-time-interaction>
|
||||
|
||||
Thresholds in ms for BPL scenarios.
|
||||
|
||||
=item B<--warning-time-total>
|
||||
|
||||
Thresholds in ms for BPL scenarios.
|
||||
|
||||
=item B<--critical-time-total>
|
||||
|
||||
Thresholds in ms for BPL scenarios.
|
||||
|
||||
=back
|
||||
|
||||
|
@ -103,7 +103,7 @@ sub set_counters {
|
||||
|
||||
$self->{maps_counters}->{cpu_usage} = [
|
||||
{
|
||||
label => 'usage-percentage',
|
||||
label => 'usage-prct',
|
||||
type => 1,
|
||||
nlabel => 'cpu.capacity.usage.percentage',
|
||||
set => {
|
||||
@ -135,6 +135,7 @@ sub set_counters {
|
||||
{
|
||||
value => 'cpu_usage_hertz',
|
||||
template => '%s',
|
||||
min => 0,
|
||||
max => 'cpu_provisioned_hertz',
|
||||
unit => 'Hz'
|
||||
}
|
||||
@ -145,7 +146,7 @@ sub set_counters {
|
||||
|
||||
$self->{maps_counters}->{cpu_contention} = [
|
||||
{
|
||||
label => 'contention-percentage',
|
||||
label => 'contention-prct',
|
||||
type => 1,
|
||||
nlabel => 'cpu.capacity.contention.percentage',
|
||||
set => {
|
||||
@ -167,7 +168,7 @@ sub set_counters {
|
||||
];
|
||||
$self->{maps_counters}->{cpu_demand} = [
|
||||
{
|
||||
label => 'demand-percentage',
|
||||
label => 'demand-prct',
|
||||
type => 1,
|
||||
nlabel => 'cpu.capacity.demand.percentage',
|
||||
set => {
|
||||
@ -175,7 +176,7 @@ sub set_counters {
|
||||
key_values => [ { name => 'prct_demand' } ],
|
||||
output_use => 'prct_demand',
|
||||
threshold_use => 'prct_demand',
|
||||
perfdatas => [ { value => 'prct_demand', template => '%s' } ]
|
||||
perfdatas => [ { value => 'prct_demand', template => '%s', unit => '%', min => 0, max => 100 } ]
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -195,6 +196,7 @@ sub set_counters {
|
||||
{
|
||||
value => 'cpu_demand_hertz',
|
||||
template => '%s',
|
||||
min => 0,
|
||||
max => 'cpu_provisioned_hertz',
|
||||
unit => 'Hz'
|
||||
}
|
||||
@ -205,7 +207,7 @@ sub set_counters {
|
||||
|
||||
$self->{maps_counters}->{cpu_corecount} = [
|
||||
{
|
||||
label => 'corecount-usage',
|
||||
label => 'corecount-usage-count',
|
||||
type => 1,
|
||||
nlabel => 'cpu.corecount.usage.count',
|
||||
set => {
|
||||
@ -302,7 +304,7 @@ __END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Monitor the status of VMware ESX hosts through vSphere 8 REST API.
|
||||
Monitor the CPU stats of VMware ESX hosts through vSphere 8 REST API.
|
||||
|
||||
Meaning of the available counters in the VMware API:
|
||||
- cpu.capacity.provisioned.HOST Capacity in kHz of the physical CPU cores.
|
||||
@ -337,61 +339,53 @@ Add counter related to CPU core count:
|
||||
|
||||
C<cpu.corecount.usage.HOST>: The number of virtual processors running on the host.
|
||||
|
||||
=item B<--warning-usage-percentage>
|
||||
=item B<--warning-contention-prct>
|
||||
|
||||
Threshold in %.
|
||||
Threshold in percentage.
|
||||
|
||||
=item B<--critical-usage-percentage>
|
||||
=item B<--critical-contention-prct>
|
||||
|
||||
Threshold in %.
|
||||
Threshold in percentage.
|
||||
|
||||
=item B<--warning-usage-frequency>
|
||||
=item B<--warning-corecount-usage-count>
|
||||
|
||||
Threshold in Hz.
|
||||
Threshold.
|
||||
|
||||
=item B<--critical-usage-frequency>
|
||||
=item B<--critical-corecount-usage-count>
|
||||
|
||||
Threshold in Hz.
|
||||
|
||||
=item B<--warning-contention-percentage>
|
||||
|
||||
Threshold in %.
|
||||
|
||||
=item B<--critical-contention-percentage>
|
||||
|
||||
Threshold in %.
|
||||
|
||||
=item B<--warning-contention-frequency>
|
||||
|
||||
Threshold in Hz.
|
||||
|
||||
=item B<--critical-contention-frequency>
|
||||
|
||||
Threshold in Hz.
|
||||
|
||||
=item B<--warning-demand-percentage>
|
||||
|
||||
Threshold in %.
|
||||
|
||||
=item B<--critical-demand-percentage>
|
||||
|
||||
Threshold in %.
|
||||
Threshold.
|
||||
|
||||
=item B<--warning-demand-frequency>
|
||||
|
||||
Threshold in Hz.
|
||||
Threshold in Hertz.
|
||||
|
||||
=item B<--critical-demand-frequency>
|
||||
|
||||
Threshold in Hz.
|
||||
Threshold in Hertz.
|
||||
|
||||
=item B<--warning-corecount-usage>
|
||||
=item B<--warning-demand-prct>
|
||||
|
||||
Threshold in number of cores.
|
||||
Threshold in percentage.
|
||||
|
||||
=item B<--critical-corecount-usage>
|
||||
=item B<--critical-demand-prct>
|
||||
|
||||
Threshold in number of cores.
|
||||
Threshold in percentage.
|
||||
|
||||
=item B<--warning-usage-frequency>
|
||||
|
||||
Threshold in Hertz.
|
||||
|
||||
=item B<--critical-usage-frequency>
|
||||
|
||||
Threshold in Hertz.
|
||||
|
||||
=item B<--warning-usage-prct>
|
||||
|
||||
Threshold in percentage.
|
||||
|
||||
=item B<--critical-usage-prct>
|
||||
|
||||
Threshold in percentage.
|
||||
|
||||
=back
|
||||
|
||||
|
117
src/apps/vmware/vsphere8/esx/mode/diskio.pm
Normal file
117
src/apps/vmware/vsphere8/esx/mode/diskio.pm
Normal file
@ -0,0 +1,117 @@
|
||||
#
|
||||
# Copyright 2025 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
# service performance.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
package apps::vmware::vsphere8::esx::mode::diskio;
|
||||
use strict;
|
||||
use warnings;
|
||||
use base qw(apps::vmware::vsphere8::esx::mode);
|
||||
|
||||
my @counters = (
|
||||
"disk.throughput.usage.HOST",
|
||||
"disk.throughput.contention.HOST"
|
||||
);
|
||||
|
||||
sub custom_diskio_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $msg = sprintf("Disk throughput usage: %s %s/s",
|
||||
$self->{perfdata}->change_bytes(value => $self->{result_values}->{throughput_bps})
|
||||
);
|
||||
return $msg;
|
||||
}
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{ name => 'diskio', type => 0 }
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{diskio} = [
|
||||
{
|
||||
label => 'usage-bps',
|
||||
type => 1,
|
||||
nlabel => 'disk.throughput.usage.bytespersecond',
|
||||
set => {
|
||||
key_values => [ { name => 'disk.throughput.usage.HOST' }, { name => 'throughput_bps' } ],
|
||||
closure_custom_output => $self->can('custom_diskio_output'),
|
||||
perfdatas => [ { value => 'throughput_bps', template => '%s', unit => 'Bps' } ]
|
||||
}
|
||||
},
|
||||
{
|
||||
label => 'contention-ms',
|
||||
type => 1,
|
||||
nlabel => 'disk.throughput.contention.milliseconds',
|
||||
set => {
|
||||
key_values => [ { name => 'disk.throughput.contention.HOST' }],
|
||||
output_template => 'Disk throughput contention is %s ms',
|
||||
output_use => 'disk.throughput.contention.HOST',
|
||||
threshold_use => 'disk.throughput.contention.HOST',
|
||||
perfdatas => [ { value => 'disk.throughput.contention.HOST', template => '%s', unit => 'ms' } ]
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my %structure = map {
|
||||
$_ => $self->get_esx_stats(%options, cid => $_, esx_id => $self->{esx_id}, esx_name => $self->{esx_name} )
|
||||
} @counters;
|
||||
$self->{diskio} = \%structure;
|
||||
|
||||
if ( defined($structure{'disk.throughput.usage.HOST'}) ) {
|
||||
$self->{diskio}->{throughput_bps} = $structure{'disk.throughput.usage.HOST'} * 1024;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Monitor the disk throughput and contention of VMware ESX hosts through vSphere 8 REST API.
|
||||
|
||||
Meaning of the available counters in the VMware API:
|
||||
- disk.throughput.usage.HOST Aggregated disk I/O rate (in kB/s), including the rates for all virtual machines running on the host during the collection interval
|
||||
- disk.throughput.contention.HOST Average amount of time (in milliseconds) for an I/O operation to complete successfully
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--warning-contention-ms>
|
||||
|
||||
Threshold in milliseconds.
|
||||
|
||||
=item B<--critical-contention-ms>
|
||||
|
||||
Threshold in milliseconds.
|
||||
|
||||
=item B<--warning-usage-bps>
|
||||
|
||||
Threshold in bytes per second.
|
||||
|
||||
=item B<--critical-usage-bps>
|
||||
|
||||
Threshold in bytes per second.
|
||||
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
@ -52,7 +52,7 @@ sub set_counters {
|
||||
|
||||
$self->{maps_counters}->{memory} = [
|
||||
{
|
||||
label => 'vms-usage-percentage',
|
||||
label => 'usage-prct',
|
||||
type => 1,
|
||||
nlabel => 'vms.memory.usage.percentage',
|
||||
set => {
|
||||
@ -72,7 +72,7 @@ sub set_counters {
|
||||
}
|
||||
},
|
||||
{
|
||||
label => 'vms-usage-bytes',
|
||||
label => 'usage-bytes',
|
||||
type => 1,
|
||||
nlabel => 'vms.memory.usage.bytes',
|
||||
set => {
|
||||
@ -119,29 +119,32 @@ sub manage_selection {
|
||||
Monitor the memory of VMware ESX hosts consumed by the virtual machines through vSphere 8 REST API.
|
||||
|
||||
Meaning of the available counters in the VMware API:
|
||||
mem.reservedCapacityPct.HOST Percent of memory that has been reserved either through VMkernel use, by userworlds or due to virtual machine memory reservations.
|
||||
mem.capacity.provisioned.HOST Total amount of memory available to the host.
|
||||
mem.capacity.usable.HOST Amount of physical memory available for use by virtual machines on this host
|
||||
mem.capacity.usage.HOST Amount of physical memory actively used
|
||||
mem.capacity.contention.HOST Percentage of time VMs are waiting to access swapped, compressed or ballooned memory.
|
||||
mem.consumed.vms.HOST Amount of physical memory consumed by VMs on this host.
|
||||
mem.consumed.userworlds.HOST Amount of physical memory consumed by userworlds on this host
|
||||
|
||||
- mem.reservedCapacityPct.HOST Percent of memory that has been reserved either through VMkernel use, by userworlds or due to virtual machine memory reservations.
|
||||
- mem.capacity.provisioned.HOST Total amount of memory available to the host.
|
||||
- mem.capacity.usable.HOST Amount of physical memory available for use by virtual machines on this host
|
||||
- mem.capacity.usage.HOST Amount of physical memory actively used
|
||||
- mem.capacity.contention.HOST Percentage of time VMs are waiting to access swapped, compressed or ballooned memory.
|
||||
- mem.consumed.vms.HOST Amount of physical memory consumed by VMs on this host.
|
||||
- mem.consumed.userworlds.HOST Amount of physical memory consumed by userworlds on this host
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--warning-vms-usage-percentage>
|
||||
=item B<--warning-usage-bytes>
|
||||
|
||||
Thresholds in percentage.
|
||||
Threshold in bytes.
|
||||
|
||||
=item B<--critical-vms-usage-percentage>
|
||||
=item B<--critical-usage-bytes>
|
||||
|
||||
Thresholds in percentage.
|
||||
Threshold in bytes.
|
||||
|
||||
=item B<--warning-vms-usage-bytes>
|
||||
=item B<--warning-usage-prct>
|
||||
|
||||
Thresholds in bytes.
|
||||
Threshold in percentage.
|
||||
|
||||
=item B<--critical-vms-usage-bytes>
|
||||
=item B<--critical-usage-prct>
|
||||
|
||||
Thresholds in bytes.
|
||||
Threshold in percentage.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
197
src/apps/vmware/vsphere8/esx/mode/network.pm
Normal file
197
src/apps/vmware/vsphere8/esx/mode/network.pm
Normal file
@ -0,0 +1,197 @@
|
||||
#
|
||||
# Copyright 2025 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
# service performance.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
package apps::vmware::vsphere8::esx::mode::network;
|
||||
use strict;
|
||||
use warnings;
|
||||
use base qw(apps::vmware::vsphere8::esx::mode);
|
||||
|
||||
my @counters = (
|
||||
#'net.throughput.provisioned.HOST', # not used atm
|
||||
'net.throughput.usable.HOST',
|
||||
'net.throughput.usage.HOST',
|
||||
#'net.throughput.contention.HOST' # pushed in manage_selection if necessary
|
||||
);
|
||||
|
||||
sub custom_network_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $msg = sprintf("Network throughput usage: %s %s/s of %s %s/s usable",
|
||||
$self->{perfdata}->change_bytes(value => $self->{result_values}->{usage_bps}),
|
||||
$self->{perfdata}->change_bytes(value => $self->{result_values}->{max_bps})
|
||||
);
|
||||
return $msg;
|
||||
}
|
||||
|
||||
# Skip contention processing if there is no available data
|
||||
sub skip_contention {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return 0 if (defined($self->{contention})
|
||||
&& ref($self->{contention}) eq 'HASH'
|
||||
&& scalar(keys %{$self->{contention}}) > 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{ name => 'network', type => 0 },
|
||||
{ name => 'contention', type => 0, cb_init => 'skip_contention' }
|
||||
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{network} = [
|
||||
{
|
||||
label => 'usage-bps',
|
||||
type => 1,
|
||||
nlabel => 'network.throughput.usage.bytespersecond',
|
||||
set => {
|
||||
key_values => [ { name => 'usage_bps' }, { name => 'max_bps' }, { name => 'usage_prct' } ],
|
||||
closure_custom_output => $self->can('custom_network_output'),
|
||||
perfdatas => [ { value => 'usage_bps', template => '%s', unit => 'Bps', min => 0, max => 'max_bps' } ]
|
||||
}
|
||||
},
|
||||
{
|
||||
label => 'usage-prct',
|
||||
type => 1,
|
||||
nlabel => 'network.throughput.usage.percent',
|
||||
set => {
|
||||
key_values => [ { name => 'usage_prct' } ],
|
||||
output_template => "%.2f%% of usable network throughput used",
|
||||
output_use => "usage_prct",
|
||||
perfdatas => [ { value => 'usage_prct', template => '%s', unit => '%', min => 0, max => '100' } ]
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{contention} = [
|
||||
{
|
||||
label => 'contention-count',
|
||||
type => 1,
|
||||
nlabel => 'network.throughput.contention.count',
|
||||
set => {
|
||||
key_values => [ { name => 'net.throughput.contention.HOST' } ],
|
||||
output_template => "%d packet(s) dropped",
|
||||
output_use => "net.throughput.contention.HOST",
|
||||
perfdatas => [ { value => 'net.throughput.contention.HOST', template => '%s', unit => '' } ]
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
|
||||
$options{options}->add_options(
|
||||
arguments => {
|
||||
'add-contention' => { name => 'add_contention' }
|
||||
}
|
||||
);
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
# If a threshold is given on rates, we enable the corresponding data collection
|
||||
if (grep {$_ =~ /contention/ && defined($self->{option_results}->{$_}) && $self->{option_results}->{$_} ne ''} keys %{$self->{option_results}}) {
|
||||
$self->{option_results}->{add_contention} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
push @counters, 'net.throughput.contention.HOST' if ($self->{option_results}->{add_contention});
|
||||
|
||||
my %structure = map {
|
||||
$_ => $self->get_esx_stats(%options, cid => $_, esx_id => $self->{esx_id}, esx_name => $self->{esx_name} )
|
||||
} @counters;
|
||||
$self->{network} = {};
|
||||
$self->{contention} = {};
|
||||
|
||||
if ( defined($structure{'net.throughput.usage.HOST'}) && defined($structure{'net.throughput.usable.HOST'})) {
|
||||
$self->{network}->{usage_bps} = $structure{'net.throughput.usage.HOST'} * 1024;
|
||||
$self->{network}->{max_bps} = $structure{'net.throughput.usable.HOST'} * 1024;
|
||||
|
||||
if ($structure{'net.throughput.usable.HOST'} != 0) {
|
||||
$self->{network}->{usage_prct} = 100 * $structure{'net.throughput.usage.HOST'} / $structure{'net.throughput.usable.HOST'};
|
||||
} else {
|
||||
$self->{network}->{usage_prct} = 0;
|
||||
}
|
||||
}
|
||||
if ( defined($structure{'net.throughput.contention.HOST'}) ) {
|
||||
$self->{contention}->{'net.throughput.contention.HOST'} = $structure{'net.throughput.contention.HOST'};
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Monitor the swap usage of VMware ESX hosts through vSphere 8 REST API.
|
||||
|
||||
- net.throughput.provisioned.HOST The maximum network bandwidth (in kB/s) for the host.
|
||||
- net.throughput.usable.HOST The currently available network bandwidth (in kB/s) for the host.
|
||||
- net.throughput.usage.HOST The current network bandwidth usage (in kB/s) for the host.
|
||||
- net.throughput.contention.HOST The aggregate network droppped packets for the host.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--add-contention>
|
||||
|
||||
Add counters related to network throughput contention.
|
||||
This option is implicitly enabled if thresholds related to contention are set.
|
||||
|
||||
=item B<--warning-contention-count>
|
||||
|
||||
Threshold.
|
||||
|
||||
=item B<--critical-contention-count>
|
||||
|
||||
Threshold.
|
||||
|
||||
=item B<--warning-usage-bps>
|
||||
|
||||
Threshold in bytes per second.
|
||||
|
||||
=item B<--critical-usage-bps>
|
||||
|
||||
Threshold in bytes per second.
|
||||
|
||||
=item B<--warning-usage-prct>
|
||||
|
||||
Threshold in percentage.
|
||||
|
||||
=item B<--critical-usage-prct>
|
||||
|
||||
Threshold in percentage.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
@ -37,7 +37,7 @@ sub set_counters {
|
||||
|
||||
$self->{maps_counters}->{power} = [
|
||||
{
|
||||
label => 'power-usage-watts',
|
||||
label => 'usage-watts',
|
||||
type => 1,
|
||||
nlabel => 'power.capacity.usage.watts',
|
||||
output_template => 'Power usage is %d Watts',
|
||||
@ -46,7 +46,7 @@ sub set_counters {
|
||||
key_values => [ { name => 'power.capacity.usage.HOST' } ],
|
||||
output_use => 'power.capacity.usage.HOST',
|
||||
threshold_use => 'power.capacity.usage.HOST',
|
||||
perfdatas => [ { value => 'power.capacity.usage.HOST', template => '%sW' } ]
|
||||
perfdatas => [ { value => 'power.capacity.usage.HOST', template => '%s', unit => 'W', min => 0 } ]
|
||||
}
|
||||
}
|
||||
];
|
||||
@ -79,11 +79,11 @@ Since our tests showed that only C<power.capacity.usage.HOST> was different from
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--warning-power-usage-watts>
|
||||
=item B<--warning-usage-watts>
|
||||
|
||||
Threshold in Watts.
|
||||
|
||||
=item B<--critical-power-usage-watts>
|
||||
=item B<--critical-usage-watts>
|
||||
|
||||
Threshold in Watts.
|
||||
|
||||
|
236
src/apps/vmware/vsphere8/esx/mode/swap.pm
Normal file
236
src/apps/vmware/vsphere8/esx/mode/swap.pm
Normal file
@ -0,0 +1,236 @@
|
||||
#
|
||||
# Copyright 2025 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
# service performance.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
package apps::vmware::vsphere8::esx::mode::swap;
|
||||
use strict;
|
||||
use warnings;
|
||||
use base qw(apps::vmware::vsphere8::esx::mode);
|
||||
|
||||
my @counters = (
|
||||
'mem.swap.current.HOST',
|
||||
'mem.swap.target.HOST',
|
||||
#'mem.swap.readrate.HOST', # pushed in manage_selection if necessary
|
||||
#'mem.swap.writerate.HOST' # pushed in manage_selection if necessary
|
||||
);
|
||||
|
||||
sub custom_swap_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $msg = sprintf("Swap usage: %s %s (max available is %s %s)",
|
||||
$self->{perfdata}->change_bytes(value => $self->{result_values}->{used_bytes}),
|
||||
$self->{perfdata}->change_bytes(value => $self->{result_values}->{max_bytes})
|
||||
);
|
||||
return $msg;
|
||||
}
|
||||
|
||||
sub custom_swap_read_rate_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $msg = sprintf("Swap read rate is: %s %s/s",
|
||||
$self->{perfdata}->change_bytes(value => $self->{result_values}->{read_rate_bps})
|
||||
);
|
||||
return $msg;
|
||||
}
|
||||
sub custom_swap_write_rate_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $msg = sprintf("Swap write rate is: %s %s/s",
|
||||
$self->{perfdata}->change_bytes(value => $self->{result_values}->{write_rate_bps})
|
||||
);
|
||||
return $msg;
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
|
||||
$options{options}->add_options(
|
||||
arguments => {
|
||||
'add-rates' => { name => 'add_rates' }
|
||||
}
|
||||
);
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
# If a threshold is given on rates, we enable the corresponding data collection
|
||||
if (grep {$_ =~ /rate/ && defined($self->{option_results}->{$_}) && $self->{option_results}->{$_} ne ''} keys %{$self->{option_results}}) {
|
||||
$self->{option_results}->{add_rates} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
# Skip rates processing if there is no available data
|
||||
sub skip_rates {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return 0 if (defined($self->{swap_rates})
|
||||
&& ref($self->{swap_rates}) eq 'HASH'
|
||||
&& scalar(keys %{$self->{swap_rates}}) > 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{ name => 'swap_usage', type => 0 },
|
||||
{ name => 'swap_rates', type => 0, cb_init => 'skip_rates' }
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{swap_usage} = [
|
||||
{
|
||||
label => 'usage-bytes',
|
||||
type => 1,
|
||||
nlabel => 'swap.usage.bytes',
|
||||
set => {
|
||||
key_values => [ { name => 'used_bytes' }, { name => 'max_bytes' }, { name => 'used_prct' } ],
|
||||
closure_custom_output => $self->can('custom_swap_output'),
|
||||
perfdatas => [ { value => 'used_bytes', template => '%s', unit => 'B', max => 'max_bytes' } ]
|
||||
},
|
||||
},
|
||||
{
|
||||
label => 'usage-prct',
|
||||
type => 1,
|
||||
nlabel => 'swap.usage.percent',
|
||||
set => {
|
||||
key_values => [ { name => 'used_prct' } ],
|
||||
output_template => "Percent used: %.2f%%",
|
||||
output_use => 'used_prct',
|
||||
perfdatas => [ { value => 'used_prct', template => '%s', unit => '%', min => 0, max => 100 } ]
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{swap_rates} = [
|
||||
{
|
||||
label => 'read-rate-bps',
|
||||
type => 1,
|
||||
nlabel => 'swap.read-rate.bytespersecond',
|
||||
set => {
|
||||
closure_custom_output => $self->can('custom_swap_read_rate_output'),
|
||||
key_values => [ { name => 'read_rate_bps' } ],
|
||||
perfdatas => [ { value => 'read_rate_bps', template => '%s', unit => 'Bps' } ]
|
||||
}
|
||||
},
|
||||
{
|
||||
label => 'write-rate-bps',
|
||||
type => 1,
|
||||
nlabel => 'swap.write-rate.bytespersecond',
|
||||
set => {
|
||||
closure_custom_output => $self->can('custom_swap_write_rate_output'),
|
||||
key_values => [ { name => 'write_rate_bps' } ],
|
||||
perfdatas => [ { value => 'write_rate_bps', template => '%s', unit => 'Bps' } ]
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
push @counters, 'mem.swap.readrate.HOST', 'mem.swap.writerate.HOST' if ($self->{option_results}->{add_rates});
|
||||
|
||||
my %structure = map {
|
||||
$_ => $self->get_esx_stats(%options, cid => $_, esx_id => $self->{esx_id}, esx_name => $self->{esx_name})
|
||||
} @counters;
|
||||
|
||||
$self->{swap_usage} = {};
|
||||
|
||||
if (defined($structure{'mem.swap.current.HOST'}) && defined($structure{'mem.swap.target.HOST'})) {
|
||||
$self->{swap_usage}->{used_bytes} = $structure{'mem.swap.current.HOST'} * 1024;
|
||||
$self->{swap_usage}->{max_bytes} = $structure{'mem.swap.target.HOST'} * 1024;
|
||||
if ($structure{'mem.swap.target.HOST'} != 0) {
|
||||
$self->{swap_usage}->{used_prct} = 100 * $structure{'mem.swap.current.HOST'} / $structure{'mem.swap.target.HOST'};
|
||||
}
|
||||
else {
|
||||
$self->{swap_usage}->{used_prct} = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (defined($structure{'mem.swap.readrate.HOST'})) {
|
||||
$self->{swap_rates}->{read_rate_bps} = $structure{'mem.swap.readrate.HOST'} * 1024;
|
||||
}
|
||||
|
||||
if (defined($structure{'mem.swap.writerate.HOST'})) {
|
||||
$self->{swap_rates}->{write_rate_bps} = $structure{'mem.swap.writerate.HOST'} * 1024;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Monitor the swap usage of VMware ESX hosts through vSphere 8 REST API.
|
||||
|
||||
Meaning of the available counters in the VMware API:
|
||||
- mem.swap.current.HOST Amount (in kB) of memory that is used by swap. Sum of memory swapped of all powered on VMs and vSphere services on the host.
|
||||
- mem.swap.target.HOST Target size (in kB) for the virtual machine swap file. The VMkernel manages swapping by comparing swaptarget against swapped.
|
||||
- mem.swap.readrate.HOST Rate (in kB/s) at which memory is swapped from disk into active memory during the interval. This counter applies to virtual machines and is generally more useful than the swapin counter to determine if the virtual machine is running slow due to swapping, especially when looking at real-time statistics.
|
||||
- mem.swap.writerate.HOST Rate (in kB/s) at which memory is being swapped from active memory to disk during the current interval. This counter applies to virtual machines and is generally more useful than the swapout counter to determine if the virtual machine is running slow due to swapping, especially when looking at real-time statistics.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--add-rates>
|
||||
|
||||
Add counters related to swap read and write rates.
|
||||
This option is implicitly enabled if thresholds related to rates are set.
|
||||
|
||||
=item B<--warning-read-rate-bps>
|
||||
|
||||
Threshold in bytes per second.
|
||||
|
||||
=item B<--critical-read-rate-bps>
|
||||
|
||||
Threshold in bytes per second.
|
||||
|
||||
=item B<--warning-usage-bytes>
|
||||
|
||||
Threshold in B.
|
||||
|
||||
=item B<--critical-usage-bytes>
|
||||
|
||||
Threshold in B.
|
||||
|
||||
=item B<--warning-usage-prct>
|
||||
|
||||
Threshold in percentage.
|
||||
|
||||
=item B<--critical-usage-prct>
|
||||
|
||||
Threshold in percentage.
|
||||
|
||||
=item B<--warning-write-rate-bps>
|
||||
|
||||
Threshold in bytes per second.
|
||||
|
||||
=item B<--critical-write-rate-bps>
|
||||
|
||||
Threshold in bytes per second.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
@ -33,9 +33,12 @@ sub new {
|
||||
$self->{modes} = {
|
||||
'cpu' => 'apps::vmware::vsphere8::esx::mode::cpu',
|
||||
'discovery' => 'apps::vmware::vsphere8::esx::mode::discovery',
|
||||
'disk-io' => 'apps::vmware::vsphere8::esx::mode::diskio',
|
||||
'host-status' => 'apps::vmware::vsphere8::esx::mode::hoststatus',
|
||||
'memory' => 'apps::vmware::vsphere8::esx::mode::memory',
|
||||
'network' => 'apps::vmware::vsphere8::esx::mode::network',
|
||||
'power' => 'apps::vmware::vsphere8::esx::mode::power',
|
||||
'swap' => 'apps::vmware::vsphere8::esx::mode::swap',
|
||||
};
|
||||
|
||||
$self->{custom_modes}->{api} = 'apps::vmware::vsphere8::custom::api';
|
||||
|
@ -24,98 +24,111 @@ use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold);
|
||||
|
||||
sub custom_status_perfdata {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{output}->perfdata_add(label => 'running_last_changed', unit => 's',
|
||||
value => sprintf("%d", $self->{result_values}->{running_last_changed}),
|
||||
min => 0);
|
||||
$self->{output}->perfdata_add(label => 'running_last_saved', unit => 's',
|
||||
value => sprintf("%d", $self->{result_values}->{running_last_saved}),
|
||||
min => 0);
|
||||
$self->{output}->perfdata_add(label => 'startup_last_changed', unit => 's',
|
||||
value => sprintf("%d", $self->{result_values}->{startup_last_changed}),
|
||||
min => 0);
|
||||
}
|
||||
use centreon::plugins::misc;
|
||||
|
||||
sub custom_status_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $msg = sprintf("Configuration Running Last Changed: %s, Running Last Saved: %s, Startup Last Changed: %s",
|
||||
($self->{result_values}->{running_last_changed} > 0) ? centreon::plugins::misc::change_seconds(value => $self->{result_values}->{running_last_changed}) : "-",
|
||||
($self->{result_values}->{running_last_saved} > 0) ? centreon::plugins::misc::change_seconds(value => $self->{result_values}->{running_last_saved}) : "-",
|
||||
($self->{result_values}->{startup_last_changed} > 0) ? centreon::plugins::misc::change_seconds(value => $self->{result_values}->{startup_last_changed}) : "-");
|
||||
return $msg;
|
||||
}
|
||||
|
||||
sub custom_status_calc {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{result_values}->{running_last_changed} = $options{new_datas}->{$self->{instance} . '_running_last_changed'};
|
||||
$self->{result_values}->{running_last_saved} = $options{new_datas}->{$self->{instance} . '_running_last_saved'};
|
||||
$self->{result_values}->{startup_last_changed} = $options{new_datas}->{$self->{instance} . '_startup_last_changed'};
|
||||
return 0;
|
||||
return $self->{result_values}->{output_message};
|
||||
}
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{ name => 'global', type => 0 },
|
||||
{ name => 'global', type => 0 }
|
||||
];
|
||||
|
||||
|
||||
$self->{maps_counters}->{global} = [
|
||||
{ label => 'status', threshold => 0, set => {
|
||||
key_values => [ { name => 'running_last_changed' }, { name => 'running_last_saved' }, { name => 'startup_last_changed' } ],
|
||||
closure_custom_calc => $self->can('custom_status_calc'),
|
||||
{
|
||||
label => 'config-running-ahead', nlabel => 'configuration.running.ahead.since.seconds',
|
||||
set => {
|
||||
key_values => [ { name => 'running_ahead' }, { name => 'output_message' } ],
|
||||
closure_custom_output => $self->can('custom_status_output'),
|
||||
closure_custom_perfdata => $self->can('custom_status_perfdata'),
|
||||
closure_custom_threshold_check => \&catalog_status_threshold,
|
||||
perfdatas => [
|
||||
{ template => '%s', min => 0, unit => 's' }
|
||||
]
|
||||
}
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments =>
|
||||
{
|
||||
"warning-status:s" => { name => 'warning_status', default => '' },
|
||||
"critical-status:s" => { name => 'critical_status', default => '%{running_last_changed} > %{running_last_saved}' },
|
||||
});
|
||||
|
||||
$options{options}->add_options(arguments => {});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
$self->change_macros(macros => ['warning_status', 'critical_status']);
|
||||
}
|
||||
|
||||
my $oid_ccmHistoryRunningLastChanged = '.1.3.6.1.4.1.9.9.43.1.1.1.0';
|
||||
my $oid_ccmHistoryRunningLastSaved = '.1.3.6.1.4.1.9.9.43.1.1.2.0';
|
||||
my $oid_ccmHistoryStartupLastChanged = '.1.3.6.1.4.1.9.9.43.1.1.3.0';
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
$self->{snmp} = $options{snmp};
|
||||
|
||||
$self->{global} = {};
|
||||
my $oid_ccmHistoryRunningLastChanged = '.1.3.6.1.4.1.9.9.43.1.1.1.0';
|
||||
my $oid_ccmHistoryRunningLastSaved = '.1.3.6.1.4.1.9.9.43.1.1.2.0';
|
||||
my $oid_ccmHistoryStartupLastChanged = '.1.3.6.1.4.1.9.9.43.1.1.3.0';
|
||||
my $oid_sysUpTime = '.1.3.6.1.2.1.1.3.0';
|
||||
my $oid_snmpEngineTime = '.1.3.6.1.6.3.10.2.1.3.0';
|
||||
|
||||
my $ctime = time();
|
||||
my $runningChangedMarginAfterReload = 300;
|
||||
|
||||
my $results = $options{snmp}->get_leef(
|
||||
oids => [
|
||||
$oid_ccmHistoryRunningLastChanged,
|
||||
$oid_ccmHistoryRunningLastSaved,
|
||||
$oid_ccmHistoryStartupLastChanged,
|
||||
$oid_sysUpTime,
|
||||
$oid_snmpEngineTime
|
||||
],
|
||||
nothing_quit => 1
|
||||
);
|
||||
|
||||
my $uptime = defined($results->{$oid_snmpEngineTime}) ? $results->{$oid_snmpEngineTime} : ($results->{$oid_sysUpTime} / 100);
|
||||
|
||||
my $start_time = $ctime - $uptime;
|
||||
my $ccmHistoryRunningLastChanged = $start_time + ($results->{$oid_ccmHistoryRunningLastChanged} / 100);
|
||||
my $ccmHistoryRunningLastSaved = $start_time + ($results->{$oid_ccmHistoryRunningLastSaved} / 100);
|
||||
my $ccmHistoryStartupLastChanged = $start_time + ($results->{$oid_ccmHistoryStartupLastChanged} / 100);
|
||||
|
||||
$self->{output}->output_add(long_msg => sprintf(
|
||||
"ccmHistoryRunningLastChanged: %s (%s)",
|
||||
$ccmHistoryRunningLastChanged,
|
||||
scalar(localtime($ccmHistoryRunningLastChanged)))
|
||||
);
|
||||
$self->{output}->output_add(long_msg => sprintf(
|
||||
"ccmHistoryRunningLastSaved: %s (%s)",
|
||||
$ccmHistoryRunningLastSaved,
|
||||
scalar(localtime($ccmHistoryRunningLastSaved)))
|
||||
);
|
||||
$self->{output}->output_add(long_msg => sprintf(
|
||||
"ccmHistoryStartupLastChanged: %s (%s)",
|
||||
$ccmHistoryStartupLastChanged,
|
||||
scalar(localtime($ccmHistoryStartupLastChanged)))
|
||||
);
|
||||
|
||||
my $runningUnchangedDuration = $ctime - $ccmHistoryRunningLastChanged;
|
||||
my $startupUnchangedDuration = $ctime - $ccmHistoryStartupLastChanged;
|
||||
|
||||
my $runningAhead = 0;
|
||||
my $output = 'saved config is up to date';
|
||||
if ($runningUnchangedDuration < $startupUnchangedDuration) {
|
||||
if (($runningUnchangedDuration + $runningChangedMarginAfterReload) > $uptime) {
|
||||
$output = sprintf("running config has not changed since reload (using a %d second margin)", $runningChangedMarginAfterReload);
|
||||
} else {
|
||||
$output = sprintf(
|
||||
"running config is ahead of startup config since %s. changes will be lost in case of a reboot",
|
||||
centreon::plugins::misc::change_seconds(value => $runningUnchangedDuration)
|
||||
);
|
||||
$runningAhead = $runningUnchangedDuration;
|
||||
}
|
||||
}
|
||||
|
||||
$self->{results} = $self->{snmp}->get_leef(oids => [ $oid_ccmHistoryRunningLastChanged, $oid_ccmHistoryRunningLastSaved,
|
||||
$oid_ccmHistoryStartupLastChanged ], nothing_quit => 1);
|
||||
|
||||
$self->{global} = {
|
||||
running_last_changed => $self->{results}->{$oid_ccmHistoryRunningLastChanged} / 100,
|
||||
running_last_saved => $self->{results}->{$oid_ccmHistoryRunningLastSaved} / 100,
|
||||
startup_last_changed => $self->{results}->{$oid_ccmHistoryStartupLastChanged} / 100,
|
||||
output_message => $output,
|
||||
running_ahead => $runningAhead
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,15 +142,13 @@ Check Cisco changed and saved configurations (CISCO-CONFIG-MAN-MIB).
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--warning-status>
|
||||
=item B<--warning-config-running-ahead>
|
||||
|
||||
Define the conditions to match for the status to be WARNING (default: '').
|
||||
You can use the following variables: %{running_last_changed}, %{running_last_saved}, %{startup_last_changed}
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-status>
|
||||
=item B<--critical-config-running-ahead>
|
||||
|
||||
Define the conditions to match for the status to be CRITICAL (default: '%{running_last_changed} > %{running_last_saved}').
|
||||
You can use the following variables: %{running_last_changed}, %{running_last_saved}, %{startup_last_changed}
|
||||
Thresholds.
|
||||
|
||||
=back
|
||||
|
||||
|
203
src/centreon/common/fortinet/fortigate/snmp/mode/listswitches.pm
Normal file
203
src/centreon/common/fortinet/fortigate/snmp/mode/listswitches.pm
Normal file
@ -0,0 +1,203 @@
|
||||
#
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
# service performance.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
package centreon::common::fortinet::fortigate::snmp::mode::listswitches;
|
||||
|
||||
use base qw(centreon::plugins::mode);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $mapping_status = { 0 => 'down', 1 => 'up' };
|
||||
my $map_admin_connection_state = { 0 => 'discovered', 1 => 'disable', 2 => 'authorized' };
|
||||
|
||||
my $mapping = {
|
||||
serial => { oid => '.1.3.6.1.4.1.12356.101.24.1.1.1.3' },# fgSwDeviceSerialNum
|
||||
name => { oid => '.1.3.6.1.4.1.12356.101.24.1.1.1.4' },# fgSwDeviceName
|
||||
version => { oid => '.1.3.6.1.4.1.12356.101.24.1.1.1.5' },# fgSwDeviceVersion
|
||||
admin => { oid => '.1.3.6.1.4.1.12356.101.24.1.1.1.6', map => $map_admin_connection_state },# fgSwDeviceAuthorized
|
||||
state => { oid => '.1.3.6.1.4.1.12356.101.24.1.1.1.7', map => $mapping_status },# fgSwDeviceStatus
|
||||
ip => { oid => '.1.3.6.1.4.1.12356.101.24.1.1.1.9' },# fgSwDeviceIp
|
||||
};
|
||||
my $fgSwDeviceEntry = '.1.3.6.1.4.1.12356.101.24.1.1.1';
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(
|
||||
arguments => {
|
||||
'filter-name:s' => { name => 'filter_name' },
|
||||
'filter-status:s' => { name => 'filter_status' },
|
||||
'filter-admin:s' => { name => 'filter_admin' },
|
||||
'filter-ip:s' => { name => 'filter_ip' }
|
||||
}
|
||||
);
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::init(%options);
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $snmp_result = $options{snmp}->get_table(
|
||||
oid => $fgSwDeviceEntry,
|
||||
start => $mapping->{serial},
|
||||
end => $mapping->{ip},
|
||||
nothing_quit => 1
|
||||
);
|
||||
|
||||
foreach my $oid ($options{snmp}->oid_lex_sort(sort keys %{$snmp_result})) {
|
||||
next if ($oid !~ /^$mapping->{serial}->{oid}\.(.*)$/);
|
||||
my $instance = $1;
|
||||
|
||||
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance);
|
||||
|
||||
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
|
||||
$result->{name} !~ /$self->{option_results}->{filter_name}/) {
|
||||
$self->{output}->output_add(
|
||||
long_msg => "skipping '" . $result->{name} . "': no matching filter.",
|
||||
debug => 1
|
||||
);
|
||||
next;
|
||||
}
|
||||
|
||||
if (defined($self->{option_results}->{filter_status}) && $self->{option_results}->{filter_status} ne '' &&
|
||||
$result->{state} !~ /$self->{option_results}->{filter_status}/) {
|
||||
$self->{output}->output_add(
|
||||
long_msg => "skipping '" . $result->{state} . "': no matching filter.",
|
||||
debug => 1
|
||||
);
|
||||
next;
|
||||
}
|
||||
|
||||
if (defined($self->{option_results}->{filter_admin}) && $self->{option_results}->{filter_admin} ne '' &&
|
||||
$result->{admin} !~ /$self->{option_results}->{filter_admin}/) {
|
||||
$self->{output}->output_add(
|
||||
long_msg => "skipping '" . $result->{admin} . "': no matching filter.",
|
||||
debug => 1
|
||||
);
|
||||
next;
|
||||
}
|
||||
|
||||
if (defined($self->{option_results}->{filter_ip}) && $self->{option_results}->{filter_ip} ne '' &&
|
||||
$result->{ip} !~ /$self->{option_results}->{filter_ip}/) {
|
||||
$self->{output}->output_add(
|
||||
long_msg => "skipping '" . $result->{ip} . "': no matching filter.",
|
||||
debug => 1
|
||||
);
|
||||
next;
|
||||
}
|
||||
|
||||
push @{$self->{switch}}, $result;
|
||||
}
|
||||
}
|
||||
|
||||
sub run {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->manage_selection(%options);
|
||||
|
||||
if (scalar(keys @{$self->{switch}}) <= 0) {
|
||||
$self->{output}->add_option_msg(short_msg => "No switch found matching.");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
foreach (sort @{$self->{switch}}) {
|
||||
$self->{output}->output_add(
|
||||
long_msg =>
|
||||
sprintf(
|
||||
"[Name = %s] [Serial = %s] [IP = %s] [Version = %s] [State = %s] [Admin = %s]",
|
||||
$_->{name},
|
||||
$_->{serial},
|
||||
$_->{ip},
|
||||
$_->{version},
|
||||
$_->{state},
|
||||
$_->{admin},
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$self->{output}->output_add(
|
||||
severity => 'OK',
|
||||
short_msg => 'List switches:'
|
||||
);
|
||||
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
|
||||
$self->{output}->exit();
|
||||
}
|
||||
|
||||
sub disco_format {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{output}->add_disco_format(elements => [ 'name', 'serial', 'ip', 'version', 'state', 'admin' ]);
|
||||
}
|
||||
|
||||
sub disco_show {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->manage_selection(%options);
|
||||
|
||||
foreach (@{$self->{switch}}) {
|
||||
$self->{output}->add_disco_entry(
|
||||
name => $_->{name},
|
||||
serial => $_->{serial},
|
||||
ip => $_->{ip},
|
||||
version => $_->{version},
|
||||
state => $_->{state},
|
||||
admin => $_->{admin}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
List switches managed through Fortigate Switch Controller.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--filter-name>
|
||||
|
||||
Filter switch by name (can be a regexp).
|
||||
|
||||
=item B<--filter-status>
|
||||
|
||||
Filter switch by status
|
||||
|
||||
=item B<--filter-admin>
|
||||
|
||||
Filter switch by admin connection state
|
||||
|
||||
=item B<--filter-ip>
|
||||
|
||||
Filter switch by IP (can be a regexp).
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
258
src/centreon/common/fortinet/fortigate/snmp/mode/switchusage.pm
Normal file
258
src/centreon/common/fortinet/fortigate/snmp/mode/switchusage.pm
Normal file
@ -0,0 +1,258 @@
|
||||
#
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
# service performance.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
package centreon::common::fortinet::fortigate::snmp::mode::switchusage;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold);
|
||||
use Digest::MD5 qw(md5_hex);
|
||||
|
||||
sub custom_status_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return 'status: ' . $self->{result_values}->{status} . ' [admin: ' . $self->{result_values}->{admin} . ']';
|
||||
}
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{
|
||||
name => 'switch',
|
||||
type => 1,
|
||||
cb_prefix_output => 'prefix_ap_output',
|
||||
message_multiple => 'All switches are ok',
|
||||
skipped_code => { -10 => 1 }
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{switch} = [
|
||||
{ label => 'status', threshold => 0, set => {
|
||||
key_values => [ { name => 'status' }, { name => 'admin' }, { name => 'display' } ],
|
||||
closure_custom_output => $self->can('custom_status_output'),
|
||||
closure_custom_perfdata => sub {return 0;},
|
||||
closure_custom_threshold_check => \&catalog_status_threshold
|
||||
}
|
||||
},
|
||||
{ label => 'cpu', nlabel => 'switch.cpu.utilization.percentage', set => {
|
||||
key_values => [ { name => 'cpu' }, { name => 'display' } ],
|
||||
output_template => 'cpu usage: %.2f %%',
|
||||
perfdatas => [
|
||||
{ label => 'cpu', template => '%.2f',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'memory', nlabel => 'switch.memory.usage.bytes', set => {
|
||||
key_values => [ { name => 'memory' }, { name => 'display' } ],
|
||||
output_template => 'memory usage: %.2f %%',
|
||||
perfdatas => [
|
||||
{ label => 'memory', template => '%.2f',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' }
|
||||
]
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
sub prefix_ap_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "Switch '" . $options{instance_value}->{display} . "' ";
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(
|
||||
arguments => {
|
||||
'filter-name:s' => { name => 'filter_name' },
|
||||
'filter-ip:s' => { name => 'filter_ip' },
|
||||
'unknown-status:s' => { name => 'unknown_status', default => '' },
|
||||
'warning-status:s' => { name => 'warning_status', default => '' },
|
||||
'critical-status:s' => {
|
||||
name => 'critical_status',
|
||||
default => '%{admin} eq "authorized" and %{status} eq "down"'
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
$self->change_macros(macros => [ 'unknown_status', 'warning_status', 'critical_status' ]);
|
||||
}
|
||||
|
||||
my %map_admin_connection_state = (
|
||||
0 => 'discovered', 1 => 'disable', 2 => 'authorized',
|
||||
);
|
||||
|
||||
my %map_switch_status = (
|
||||
0 => 'down', 1 => 'up'
|
||||
);
|
||||
|
||||
my $mapping = {
|
||||
fgSwDeviceAuthorized => { oid => '.1.3.6.1.4.1.12356.101.24.1.1.1.6', map => \%map_admin_connection_state },
|
||||
fgSwDeviceName => { oid => '.1.3.6.1.4.1.12356.101.24.1.1.1.4' },
|
||||
fgSwDeviceIp => { oid => '.1.3.6.1.4.1.12356.101.24.1.1.1.9' }
|
||||
};
|
||||
|
||||
my $mapping2 = {
|
||||
fgSwDeviceStatus => { oid => '.1.3.6.1.4.1.12356.101.24.1.1.1.7', map => \%map_switch_status },
|
||||
fgSwCpu => { oid => '.1.3.6.1.4.1.12356.101.24.1.1.1.11' },
|
||||
fgSwMemory => { oid => '.1.3.6.1.4.1.12356.101.24.1.1.1.12' }
|
||||
};
|
||||
my $oid_fgSwDeviceTable = '.1.3.6.1.4.1.12356.101.24.1.1.1';
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $snmp_result = $options{snmp}->get_table(
|
||||
oid => $oid_fgSwDeviceTable,
|
||||
start => $mapping->{fgSwDeviceName}->{oid},
|
||||
end => $mapping->{fgSwDeviceIp}->{oid},
|
||||
nothing_quit => 1
|
||||
);
|
||||
|
||||
$self->{switch} = {};
|
||||
foreach my $oid (sort keys %{$snmp_result}) {
|
||||
next if ($oid !~ /^$mapping->{fgSwDeviceName}->{oid}\.(.*)$/);
|
||||
my $instance = $1;
|
||||
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance);
|
||||
|
||||
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
|
||||
$result->{fgSwDeviceName} !~ /$self->{option_results}->{filter_name}/) {
|
||||
$self->{output}->output_add(
|
||||
long_msg => "skipping switch '" . $result->{fgSwDeviceName} . "'.",
|
||||
debug => 1
|
||||
);
|
||||
next;
|
||||
}
|
||||
|
||||
if (defined($self->{option_results}->{filter_ip}) && $self->{option_results}->{filter_ip} ne '' &&
|
||||
$result->{fgSwDeviceIp} !~ /$self->{option_results}->{filter_ip}/) {
|
||||
$self->{output}->output_add(
|
||||
long_msg => "skipping switch '" . $result->{fgSwDeviceIp} . "'.",
|
||||
debug => 1
|
||||
);
|
||||
next;
|
||||
}
|
||||
|
||||
$self->{switch}->{$instance} = {
|
||||
display => $result->{fgSwDeviceName},
|
||||
admin => $result->{fgSwDeviceAuthorized},
|
||||
status => 'n/a',
|
||||
};
|
||||
}
|
||||
|
||||
if (scalar(keys %{$self->{switch}}) <= 0) {
|
||||
$self->{output}->add_option_msg(short_msg => "No switch found.");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
$options{snmp}->load(
|
||||
oids => [
|
||||
$mapping2->{fgSwDeviceStatus}->{oid},
|
||||
$mapping2->{fgSwCpu}->{oid},
|
||||
$mapping2->{fgSwMemory}->{oid},
|
||||
],
|
||||
instances => [ keys %{$self->{switch}} ],
|
||||
instance_regexp => '^(.*)$'
|
||||
);
|
||||
$snmp_result = $options{snmp}->get_leef(nothing_quit => 1);
|
||||
|
||||
foreach (keys %{$self->{switch}}) {
|
||||
my $result = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result, instance => $_);
|
||||
|
||||
$self->{switch}->{$_}->{status} = $result->{fgSwDeviceStatus};
|
||||
$self->{switch}->{$_}->{cpu} = $result->{fgSwCpu};
|
||||
$self->{switch}->{$_}->{memory} = $result->{fgSwMemory};
|
||||
}
|
||||
|
||||
$self->{cache_name} = 'fortigate_' . $self->{mode} . '_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' .
|
||||
(defined($self->{option_results}->{filter_counters}) ?
|
||||
md5_hex($self->{option_results}->{filter_counters}) :
|
||||
md5_hex('all')) . '_' .
|
||||
(defined($self->{option_results}->{filter_name}) ?
|
||||
md5_hex($self->{option_results}->{filter_name}) :
|
||||
md5_hex('all'));
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check switch usage through Fortigate Switch Controller.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--warning-cpu>
|
||||
|
||||
Warning threshold (%).
|
||||
|
||||
=item B<--critical-cpu>
|
||||
|
||||
Critical threshold (%).
|
||||
|
||||
=item B<--warning-memory>
|
||||
|
||||
Warning threshold (%).
|
||||
|
||||
=item B<--critical-memory>
|
||||
|
||||
Critical threshold (%).
|
||||
|
||||
=item B<--filter-name>
|
||||
|
||||
Filter by switch name (can be a regexp).
|
||||
|
||||
=item B<--filter-ip>
|
||||
|
||||
Filter by switch IP (can be a regexp).
|
||||
|
||||
=item B<--unknown-status>
|
||||
|
||||
Define the conditions to match for the status to be UNKNOWN (default: '').
|
||||
You can use the following variables: %{admin}, %{status}, %{display}
|
||||
|
||||
=item B<--warning-status>
|
||||
|
||||
Define the conditions to match for the status to be WARNING (default: '').
|
||||
You can use the following variables: %{admin}, %{status}, %{display}
|
||||
|
||||
=item B<--critical-status>
|
||||
|
||||
Define the conditions to match for the status to be CRITICAL (default: '%{admin} eq "authorized" and %{status} eq "down"').
|
||||
You can use the following variables: %{admin}, %{status}, %{display}
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
@ -353,7 +353,7 @@ sub check_relaunch {
|
||||
}
|
||||
if ($uid != $>) {
|
||||
if ($> == 0) {
|
||||
unshift @$args, '-s', '/bin/bash', '-l', $self->{runas}, '-c', join(' ', $cmd, $rebuild_args);
|
||||
unshift @$args, '-s', '/bin/bash', '-l', $self->{runas}, '-c', join(' ', $cmd, @$rebuild_args);
|
||||
$cmd = 'su';
|
||||
} else {
|
||||
unshift @$args, '-S', '-u', $self->{runas}, $cmd, @$rebuild_args;
|
||||
|
@ -365,10 +365,27 @@ sub run_instances {
|
||||
my $message_separator = defined($options{config}->{message_separator}) ?
|
||||
$options{config}->{message_separator}: ', ';
|
||||
|
||||
# The default sort method is cmp (string comparison)
|
||||
my $sort_method = 'cmp';
|
||||
# If configured otherwise, we take it from the counter (only other method is 'num' for '<=>')
|
||||
$sort_method = $options{config}->{sort_method}
|
||||
if (defined($options{config}->{sort_method}));
|
||||
foreach my $id (sort { $sort_subs->{$sort_method}->() } keys %{$self->{$options{config}->{name}}}) {
|
||||
|
||||
# In the absence of sort_attribute the sort method is set now
|
||||
my $sort_sub = $sort_subs->{$sort_method};
|
||||
|
||||
# If sort_attribute is set, then we'll redefine how things are sorted depending on the specified sort_method
|
||||
if (defined($options{config}->{sort_attribute})) {
|
||||
my $sort_attribute = $options{config}->{sort_attribute};
|
||||
if ($sort_method eq 'cmp') {
|
||||
$sort_sub = sub { $self->{$options{config}->{name}}->{$a}->{$sort_attribute} cmp $self->{$options{config}->{name}}->{$b}->{$sort_attribute}};
|
||||
} else {
|
||||
$sort_sub = sub { $self->{$options{config}->{name}}->{$a}->{$sort_attribute} <=> $self->{$options{config}->{name}}->{$b}->{$sort_attribute}};
|
||||
}
|
||||
}
|
||||
|
||||
# Now the loop begins with the desired sorting method
|
||||
foreach my $id (sort { $sort_sub->() } keys %{$self->{$options{config}->{name}}}) {
|
||||
my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', '');
|
||||
my @exits = ();
|
||||
foreach (@{$self->{maps_counters}->{$options{config}->{name}}}) {
|
||||
@ -547,10 +564,28 @@ sub run_multiple_instances {
|
||||
|
||||
my $message_separator = defined($options{config}->{message_separator}) ?
|
||||
$options{config}->{message_separator} : ', ';
|
||||
|
||||
# The default sort method is cmp (string comparison)
|
||||
my $sort_method = 'cmp';
|
||||
# If configured otherwise, we take it from the counter (only other method is 'num' for '<=>')
|
||||
$sort_method = $options{config}->{sort_method}
|
||||
if (defined($options{config}->{sort_method}));
|
||||
foreach my $id (sort { $sort_subs->{$sort_method}->() } keys %{$self->{$options{config}->{name}}}) {
|
||||
|
||||
# In the absence of sort_attribute the sort method is set now
|
||||
my $sort_sub = $sort_subs->{$sort_method};
|
||||
|
||||
# If sort_attribute is set, then we'll redefine how things are sorted depending on the specified sort_method
|
||||
if (defined($options{config}->{sort_attribute})) {
|
||||
my $sort_attribute = $options{config}->{sort_attribute};
|
||||
if ($sort_method eq 'cmp') {
|
||||
$sort_sub = sub { $self->{$options{config}->{name}}->{$a}->{$sort_attribute} cmp $self->{$options{config}->{name}}->{$b}->{$sort_attribute}};
|
||||
} else {
|
||||
$sort_sub = sub { $self->{$options{config}->{name}}->{$a}->{$sort_attribute} <=> $self->{$options{config}->{name}}->{$b}->{$sort_attribute}};
|
||||
}
|
||||
}
|
||||
|
||||
# Now the loop begins with the desired sorting method
|
||||
foreach my $id (sort { $sort_sub->() } keys %{$self->{$options{config}->{name}}}) {
|
||||
my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', '');
|
||||
my @exits = ();
|
||||
foreach (@{$self->{maps_counters}->{$options{config}->{name}}}) {
|
||||
|
@ -31,7 +31,8 @@ sub new {
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
# Adding options specific to this mode
|
||||
$options{options}->add_options(arguments => {
|
||||
"warning:s" => { name => 'warning' },
|
||||
"critical:s" => { name => 'critical' },
|
||||
"seconds" => { name => 'seconds' }
|
||||
@ -44,10 +45,13 @@ sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::init(%options);
|
||||
|
||||
# Validating warning threshold
|
||||
if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) {
|
||||
$self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'.");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
# Validating critical threshold
|
||||
if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) {
|
||||
$self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'.");
|
||||
$self->{output}->option_exit();
|
||||
@ -57,31 +61,45 @@ sub check_options {
|
||||
sub run {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$options{sql}->connect();
|
||||
$options{sql}->connect();
|
||||
|
||||
# Checking if MySQL version is supported
|
||||
if (!($options{sql}->is_version_minimum(version => '5'))) {
|
||||
$self->{output}->add_option_msg(short_msg => "MySQL version '" . $self->{sql}->{version} . "' is not supported (need version >= '5.x').");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
# Querying MySQL for Uptime status
|
||||
$options{sql}->query(query => q{SHOW /*!50000 global */ STATUS LIKE 'Uptime'});
|
||||
my ($name, $value) = $options{sql}->fetchrow_array();
|
||||
|
||||
# Handling case where uptime value is not available
|
||||
if (!defined($value)) {
|
||||
$self->{output}->add_option_msg(short_msg => "Cannot get uptime.");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
# Checking the threshold and determining exit code
|
||||
my $exit_code = $self->{perfdata}->threshold_check(value => $value, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]);
|
||||
my $msg = sprintf("database is up since %d days", floor($value / 86400));
|
||||
|
||||
# Calculating uptime in days or seconds based on user preference
|
||||
my $uptime_days = floor($value / 86400);
|
||||
my $msg = sprintf("database is up since %d days", $uptime_days);
|
||||
if (defined($self->{option_results}->{seconds})) {
|
||||
$msg = sprintf("database is up since %d seconds", $value);
|
||||
}
|
||||
|
||||
# Adding start time information to the message
|
||||
$msg .= sprintf(" (Start time = %s)", strftime("%Y/%m/%d %H:%M:%S", localtime(time - $value)));
|
||||
|
||||
# Adding output message and performance data
|
||||
$self->{output}->output_add(
|
||||
severity => $exit_code,
|
||||
short_msg => $msg
|
||||
);
|
||||
|
||||
$self->{output}->perfdata_add(
|
||||
label => 'uptime',
|
||||
label => 'uptime',
|
||||
nlabel => 'database.uptime.seconds',
|
||||
unit => 's',
|
||||
value => $value,
|
||||
@ -90,7 +108,9 @@ sub run {
|
||||
min => 0
|
||||
);
|
||||
|
||||
# Displaying the output and exiting
|
||||
$self->{output}->display();
|
||||
|
||||
$self->{output}->exit();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2025 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
@ -48,6 +48,15 @@ sub custom_status_calc {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub custom_last_replace_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return sprintf(
|
||||
'replace last time: %s',
|
||||
centreon::plugins::misc::change_seconds(value => $self->{result_values}->{last_replace_time})
|
||||
);
|
||||
}
|
||||
|
||||
sub custom_status_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
@ -80,108 +89,127 @@ sub set_counters {
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{ name => 'global', type => 0, skipped_code => { -10 => 1 } },
|
||||
{ name => 'bpacks', type => 3, cb_prefix_output => 'prefix_bpack_output', cb_long_output => 'bpack_long_output', indent_long_output => ' ', message_multiple => 'All battery packs are ok',
|
||||
group => [
|
||||
{ name => 'bpack_global', type => 0, skipped_code => { -10 => 1 } },
|
||||
{ name => 'cartridges', display_long => 1, cb_prefix_output => 'prefix_cartridge_output', message_multiple => 'cartridges are ok', type => 1, skipped_code => { -10 => 1 } }
|
||||
]
|
||||
{ name => 'bpacks', type => 3, cb_prefix_output => 'prefix_bpack_output', cb_long_output => 'bpack_long_output', indent_long_output => ' ', message_multiple => 'All battery packs are ok',
|
||||
group => [
|
||||
{ name => 'bpack_global', type => 0, skipped_code => { -10 => 1 } },
|
||||
{ name => 'cartridges', display_long => 1, cb_prefix_output => 'prefix_cartridge_output', message_multiple => 'cartridges are ok', type => 1, skipped_code => { -10 => 1 } }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{global} = [
|
||||
{
|
||||
label => 'status',
|
||||
type => 2,
|
||||
unknown_default => '%{status} =~ /unknown/i',
|
||||
warning_default => '%{status} =~ /batteryLow/i',
|
||||
critical_default => '%{replace} =~ /yes/i',
|
||||
set => {
|
||||
key_values => [
|
||||
{
|
||||
label => 'status',
|
||||
type => 2,
|
||||
unknown_default => '%{status} =~ /unknown/i',
|
||||
warning_default => '%{status} =~ /batteryLow/i',
|
||||
critical_default => '%{replace} =~ /yes/i',
|
||||
set => {
|
||||
key_values => [
|
||||
{ name => 'upsBasicBatteryStatus' },
|
||||
{ name => 'upsAdvBatteryReplaceIndicator' },
|
||||
{ name => 'upsBasicBatteryLastReplaceDate' }
|
||||
],
|
||||
closure_custom_calc => $self->can('custom_status_calc'),
|
||||
closure_custom_output => $self->can('custom_battery_status_output'),
|
||||
closure_custom_perfdata => sub { return 0; },
|
||||
closure_custom_calc => $self->can('custom_status_calc'),
|
||||
closure_custom_output => $self->can('custom_battery_status_output'),
|
||||
closure_custom_perfdata => sub { return 0; },
|
||||
closure_custom_threshold_check => \&catalog_status_threshold_ng
|
||||
}
|
||||
},
|
||||
{ label => 'load', nlabel => 'battery.charge.remaining.percent', set => {
|
||||
key_values => [ { name => 'upsAdvBatteryCapacity' } ],
|
||||
output_template => 'remaining capacity: %s %%',
|
||||
perfdatas => [
|
||||
{ label => 'load', template => '%s', min => 0, max => 100, unit => '%' }
|
||||
]
|
||||
}
|
||||
key_values => [ { name => 'upsAdvBatteryCapacity' } ],
|
||||
output_template => 'remaining capacity: %s %%',
|
||||
perfdatas => [
|
||||
{ label => 'load',
|
||||
template => '%s',
|
||||
min => 0,
|
||||
max => 100,
|
||||
unit => '%' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'time', nlabel => 'battery.charge.remaining.minutes', set => {
|
||||
key_values => [ { name => 'upsAdvBatteryRunTimeRemaining' } ],
|
||||
output_template => 'remaining time: %.2f minutes',
|
||||
perfdatas => [
|
||||
{ label => 'load_time', template => '%.2f', min => 0, unit => 'm' }
|
||||
]
|
||||
}
|
||||
key_values => [ { name => 'upsAdvBatteryRunTimeRemaining' } ],
|
||||
output_template => 'remaining time: %.2f minutes',
|
||||
perfdatas => [
|
||||
{ label => 'load_time',
|
||||
template => '%.2f',
|
||||
min => 0,
|
||||
unit => 'm' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'timeon', nlabel => 'battery.timeon.minutes', set => {
|
||||
key_values => [ { name => 'upsBasicBatteryTimeOnBattery' } ],
|
||||
output_template => 'time on battery: %.2f minutes',
|
||||
perfdatas => [
|
||||
{ label => 'timeon', template => '%.2f', min => 0, unit => 'm' }
|
||||
]
|
||||
}
|
||||
key_values => [ { name => 'upsBasicBatteryTimeOnBattery' } ],
|
||||
output_template => 'time on battery: %.2f minutes',
|
||||
perfdatas => [
|
||||
{ label => 'timeon',
|
||||
template => '%.2f',
|
||||
min => 0,
|
||||
unit => 'm' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'current', nlabel => 'battery.current.ampere', set => {
|
||||
key_values => [ { name => 'upsAdvBatteryCurrent' } ],
|
||||
output_template => 'current: %s A',
|
||||
perfdatas => [
|
||||
{ label => 'current', template => '%s', min => 0, unit => 'A' }
|
||||
]
|
||||
}
|
||||
key_values => [ { name => 'upsAdvBatteryCurrent' } ],
|
||||
output_template => 'current: %s A',
|
||||
perfdatas => [
|
||||
{ label => 'current',
|
||||
template => '%s',
|
||||
min => 0,
|
||||
unit => 'A' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'voltage', nlabel => 'battery.voltage.volt', set => {
|
||||
key_values => [ { name => 'upsAdvBatteryActualVoltage' } ],
|
||||
output_template => 'voltage: %s V',
|
||||
perfdatas => [
|
||||
{ label => 'voltage', template => '%s', unit => 'V' }
|
||||
]
|
||||
}
|
||||
key_values => [ { name => 'upsAdvBatteryActualVoltage' } ],
|
||||
output_template => 'voltage: %s V',
|
||||
perfdatas => [
|
||||
{ label => 'voltage',
|
||||
template => '%s',
|
||||
unit => 'V' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'temperature', nlabel => 'battery.temperature.celsius', set => {
|
||||
key_values => [ { name => 'upsAdvBatteryTemperature' } ],
|
||||
output_template => 'temperature: %s C',
|
||||
perfdatas => [
|
||||
{ label => 'temperature', template => '%s', unit => 'C'}
|
||||
]
|
||||
}
|
||||
key_values => [ { name => 'upsAdvBatteryTemperature' } ],
|
||||
output_template => 'temperature: %s C',
|
||||
perfdatas => [
|
||||
{ label => 'temperature',
|
||||
template => '%s',
|
||||
unit => 'C' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'replace-lasttime', nlabel => 'battery.replace.lasttime.seconds', display_ok => 0, set => {
|
||||
key_values => [ { name => 'last_replace_time' } ],
|
||||
output_template => 'replace last time: %s s',
|
||||
perfdatas => [
|
||||
{ label => 'replace_last_time', template => '%s', unit => 's'}
|
||||
]
|
||||
}
|
||||
key_values => [ { name => 'last_replace_time' } ],
|
||||
closure_custom_output => $self->can('custom_last_replace_output'),
|
||||
perfdatas => [
|
||||
{ label => 'replace_last_time',
|
||||
template => '%s',
|
||||
unit => 's' }
|
||||
]
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{bpack_global} = [
|
||||
{ label => 'battery-pack-status', type => 2, critical_default => '%{status} ne "OK"', set => {
|
||||
key_values => [ { name => 'status' }, { name => 'display' } ],
|
||||
closure_custom_output => $self->can('custom_status_output'),
|
||||
closure_custom_perfdata => sub { return 0; },
|
||||
closure_custom_threshold_check => \&catalog_status_threshold_ng
|
||||
}
|
||||
key_values => [ { name => 'status' }, { name => 'display' } ],
|
||||
closure_custom_output => $self->can('custom_status_output'),
|
||||
closure_custom_perfdata => sub { return 0; },
|
||||
closure_custom_threshold_check => \&catalog_status_threshold_ng
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{cartridges} = [
|
||||
{ label => 'cartridge-status', type => 2, critical_default => '%{status} ne "OK"', set => {
|
||||
key_values => [ { name => 'status' }, { name => 'display' } ],
|
||||
closure_custom_output => $self->can('custom_status_output'),
|
||||
closure_custom_perfdata => sub { return 0; },
|
||||
closure_custom_threshold_check => \&catalog_status_threshold_ng
|
||||
}
|
||||
key_values => [ { name => 'status' }, { name => 'display' } ],
|
||||
closure_custom_output => $self->can('custom_status_output'),
|
||||
closure_custom_perfdata => sub { return 0; },
|
||||
closure_custom_threshold_check => \&catalog_status_threshold_ng
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
@ -221,17 +249,17 @@ my $map_replace_status = {
|
||||
};
|
||||
|
||||
my $mapping = {
|
||||
upsBasicBatteryStatus => { oid => '.1.3.6.1.4.1.318.1.1.1.2.1.1', map => $map_battery_status },
|
||||
upsBasicBatteryTimeOnBattery => { oid => '.1.3.6.1.4.1.318.1.1.1.2.1.2' },
|
||||
upsBasicBatteryLastReplaceDate => { oid => '.1.3.6.1.4.1.318.1.1.1.2.1.3' }
|
||||
upsBasicBatteryStatus => { oid => '.1.3.6.1.4.1.318.1.1.1.2.1.1', map => $map_battery_status },
|
||||
upsBasicBatteryTimeOnBattery => { oid => '.1.3.6.1.4.1.318.1.1.1.2.1.2' },
|
||||
upsBasicBatteryLastReplaceDate => { oid => '.1.3.6.1.4.1.318.1.1.1.2.1.3' }
|
||||
};
|
||||
my $mapping2 = {
|
||||
upsAdvBatteryCapacity => { oid => '.1.3.6.1.4.1.318.1.1.1.2.2.1' },
|
||||
upsAdvBatteryTemperature => { oid => '.1.3.6.1.4.1.318.1.1.1.2.2.2' },
|
||||
upsAdvBatteryRunTimeRemaining => { oid => '.1.3.6.1.4.1.318.1.1.1.2.2.3' },
|
||||
upsAdvBatteryReplaceIndicator => { oid => '.1.3.6.1.4.1.318.1.1.1.2.2.4', map => $map_replace_status },
|
||||
upsAdvBatteryActualVoltage => { oid => '.1.3.6.1.4.1.318.1.1.1.2.2.8' },
|
||||
upsAdvBatteryCurrent => { oid => '.1.3.6.1.4.1.318.1.1.1.2.2.9' }
|
||||
upsAdvBatteryCapacity => { oid => '.1.3.6.1.4.1.318.1.1.1.2.2.1' },
|
||||
upsAdvBatteryTemperature => { oid => '.1.3.6.1.4.1.318.1.1.1.2.2.2' },
|
||||
upsAdvBatteryRunTimeRemaining => { oid => '.1.3.6.1.4.1.318.1.1.1.2.2.3' },
|
||||
upsAdvBatteryReplaceIndicator => { oid => '.1.3.6.1.4.1.318.1.1.1.2.2.4', map => $map_replace_status },
|
||||
upsAdvBatteryActualVoltage => { oid => '.1.3.6.1.4.1.318.1.1.1.2.2.8' },
|
||||
upsAdvBatteryCurrent => { oid => '.1.3.6.1.4.1.318.1.1.1.2.2.9' }
|
||||
};
|
||||
my $oid_upsBasicBattery = '.1.3.6.1.4.1.318.1.1.1.2.1';
|
||||
my $oid_upsAdvBattery = '.1.3.6.1.4.1.318.1.1.1.2.2';
|
||||
@ -239,11 +267,11 @@ my $oid_upsHighPrecBatteryPackOnlyStatus = '.1.3.6.1.4.1.318.1.1.1.2.3.10.4.1.5'
|
||||
my $oid_upsHighPrecBatteryPackCartridgeStatus = '.1.3.6.1.4.1.318.1.1.1.2.3.10.2.1.10';
|
||||
|
||||
my $map_battery_pack_status = {
|
||||
0 => 'disconnected', 1 => 'overvoltage',
|
||||
2 => 'needsReplacement', 3 => 'overtemperatureCritical',
|
||||
4 => 'charger', 5 => 'temperatureSensor',
|
||||
6 => 'busSoftStart', 7 => 'overtemperatureWarning',
|
||||
8 => 'generalError', 9 => 'communication',
|
||||
0 => 'disconnected', 1 => 'overvoltage',
|
||||
2 => 'needsReplacement', 3 => 'overtemperatureCritical',
|
||||
4 => 'charger', 5 => 'temperatureSensor',
|
||||
6 => 'busSoftStart', 7 => 'overtemperatureWarning',
|
||||
8 => 'generalError', 9 => 'communication',
|
||||
10 => 'disconnectedFrame', 11 => 'firmwareMismatch'
|
||||
};
|
||||
|
||||
@ -257,12 +285,12 @@ sub add_battery_pack {
|
||||
$oid =~ /^$oid_upsHighPrecBatteryPackOnlyStatus\.(\d+)/;
|
||||
my $pack_index = $1;
|
||||
$self->{bpacks}->{$pack_index} = {
|
||||
display => $pack_index,
|
||||
display => $pack_index,
|
||||
bpack_global => {
|
||||
display => $pack_index,
|
||||
status => 'OK'
|
||||
status => 'OK'
|
||||
},
|
||||
cartridges => {}
|
||||
cartridges => {}
|
||||
};
|
||||
|
||||
my $status = '';
|
||||
@ -285,14 +313,14 @@ sub add_battery_pack {
|
||||
my ($pack_index, $cartridge_index) = ($1, $2);
|
||||
if (!defined($self->{bpacks}->{$pack_index})) {
|
||||
$self->{bpacks}->{$pack_index} = {
|
||||
display => $pack_index,
|
||||
display => $pack_index,
|
||||
cartridges => {}
|
||||
};
|
||||
}
|
||||
|
||||
$self->{bpacks}->{$pack_index}->{cartridges}->{$cartridge_index} = {
|
||||
display => $cartridge_index,
|
||||
status => 'OK'
|
||||
status => 'OK'
|
||||
};
|
||||
|
||||
my $status = '';
|
||||
@ -313,7 +341,7 @@ sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $snmp_result = $options{snmp}->get_multiple_table(
|
||||
oids => [
|
||||
oids => [
|
||||
{ oid => $oid_upsBasicBattery },
|
||||
{ oid => $oid_upsAdvBattery, end => $mapping2->{upsAdvBatteryCurrent}->{oid} },
|
||||
{ oid => $oid_upsHighPrecBatteryPackCartridgeStatus },
|
||||
@ -344,7 +372,7 @@ sub manage_selection {
|
||||
}
|
||||
|
||||
$self->add_battery_pack(snmp_result => $snmp_result);
|
||||
|
||||
|
||||
}
|
||||
|
||||
1;
|
||||
@ -360,62 +388,112 @@ Check battery status and battery charge remaining.
|
||||
=item B<--filter-counters>
|
||||
|
||||
Only display some counters (regexp can be used).
|
||||
Example: --filter-counters='^status|load$'
|
||||
Example: C<--filter-counters='^status|load$'>
|
||||
|
||||
=item B<--replace-lasttime-format>
|
||||
|
||||
Define the date format (default: '%m/%d/%Y').
|
||||
Define the date format (default: C<%m/%d/%Y>).
|
||||
|
||||
=item B<--unknown-status>
|
||||
|
||||
Define the conditions to match for the status to be UNKNOWN (default: '%{status} =~ /unknown/i').
|
||||
Define the conditions to match for the status to be UNKNOWN (default: C<%{status} =~ /unknown/i>).
|
||||
You can use the following variables: %{status}, %{replace}
|
||||
|
||||
=item B<--warning-status>
|
||||
|
||||
Define the conditions to match for the status to be WARNING (default: '%{status} =~ /batteryLow/i').
|
||||
You can use the following variables: %{status}, %{replace}
|
||||
Define the conditions to match for the status to be WARNING (default: C<%{status} =~ /batteryLow/i>).
|
||||
You can use the following variables: C<%{status}>, C<%{replace}>
|
||||
|
||||
=item B<--critical-status>
|
||||
|
||||
Define the conditions to match for the status to be CRITICAL (default: '%{replace} =~ /yes/i').
|
||||
You can use the following variables: %{status}, %{replace}
|
||||
Define the conditions to match for the status to be CRITICAL (default: C<%{replace} =~ /yes/i>).
|
||||
You can use the following variables: C<%{status}>, C<%{replace}>
|
||||
|
||||
=item B<--unknown-battery-pack-status>
|
||||
|
||||
Define the conditions to match for the status to be UNKNOWN.
|
||||
You can use the following variables: %{status}
|
||||
You can use the following variables: C<%{status}>
|
||||
|
||||
=item B<--warning-battery-pack-status>
|
||||
|
||||
Define the conditions to match for the status to be WARNING.
|
||||
You can use the following variables: %{status}
|
||||
You can use the following variables: C<%{status}>
|
||||
|
||||
=item B<--critical-battery-pack-status>
|
||||
|
||||
Define the conditions to match for the status to be CRITICAL (default: '%{status} ne "OK"').
|
||||
You can use the following variables: %{status}
|
||||
Define the conditions to match for the status to be CRITICAL (default: C<%{status} ne "OK">).
|
||||
You can use the following variables: C<%{status}>
|
||||
|
||||
=item B<--unknown-cartridge-status>
|
||||
|
||||
Define the conditions to match for the status to be UNKNOWN.
|
||||
You can use the following variables: %{status}
|
||||
You can use the following variables: C<%{status}>
|
||||
|
||||
=item B<--warning-cartridge-status>
|
||||
|
||||
Define the conditions to match for the status to be WARNING.
|
||||
You can use the following variables: %{status}
|
||||
You can use the following variables: C<%{status}>
|
||||
|
||||
=item B<--critical-cartridge-status>
|
||||
|
||||
Define the conditions to match for the status to be CRITICAL (default: '%{status} ne "OK"').
|
||||
You can use the following variables: %{status}
|
||||
Define the conditions to match for the status to be CRITICAL (default: C<%{status} ne "OK">).
|
||||
You can use the following variables: C<%{status}>
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
=item B<--warning-load>
|
||||
|
||||
Thresholds.
|
||||
Can be: 'load', 'voltage', 'current',
|
||||
'temperature', 'time', 'replace-lasttime', 'timeon'.
|
||||
Warning threshold for battery load (in %).
|
||||
|
||||
=item B<--critical-load>
|
||||
|
||||
Critical threshold for battery load (in %).
|
||||
|
||||
=item B<--warning-voltage>
|
||||
|
||||
Warning threshold for battery voltage (in V).
|
||||
|
||||
=item B<--critical-voltage>
|
||||
|
||||
Critical threshold for battery voltage (in V).
|
||||
|
||||
=item B<--warning-current>
|
||||
|
||||
Warning threshold for battery current (in A).
|
||||
|
||||
=item B<--critical-current>
|
||||
|
||||
Critical threshold for battery current (in A).
|
||||
|
||||
=item B<--warning-temperature>
|
||||
|
||||
Warning threshold for battery temperature (in C).
|
||||
|
||||
=item B<--critical-temperature>
|
||||
|
||||
Critical threshold for battery temperature (in C).
|
||||
|
||||
=item B<--warning-time>
|
||||
|
||||
Warning threshold for battery remaining time (in minutes).
|
||||
|
||||
=item B<--critical-time>
|
||||
|
||||
Critical threshold for battery remaining time (in minutes).
|
||||
|
||||
=item B<--warning-replace-lasttime>
|
||||
|
||||
Warning threshold for battery last replace time (in seconds).
|
||||
|
||||
=item B<--critical-replace-lasttime>
|
||||
|
||||
Critical threshold for battery last replace time (in seconds).
|
||||
|
||||
=item B<--warning-timeon>
|
||||
|
||||
Warning threshold for time on battery (in minutes).
|
||||
|
||||
=item B<--critical-timeon>
|
||||
|
||||
Critical threshold for time on battery (in minutes).
|
||||
|
||||
=back
|
||||
|
||||
|
@ -75,7 +75,7 @@ Check hardware.
|
||||
=item B<--component>
|
||||
|
||||
Which component to check (default: '.*').
|
||||
Can be: 'psu', 'temperature', 'fan', 'fantry'.
|
||||
Can be: C<psu>, C<temperature>, C<fan>, C<fantray>.
|
||||
|
||||
=item B<--filter>
|
||||
|
||||
|
@ -26,6 +26,24 @@ use strict;
|
||||
use warnings;
|
||||
use Digest::MD5 qw(md5_hex);
|
||||
|
||||
sub prefix_vs_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "Virtual server '" . $options{instance_value}->{display} . "' : ";
|
||||
}
|
||||
|
||||
sub vs_long_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "checking virtual server '" . $options{instance_value}->{display} . "'";
|
||||
}
|
||||
|
||||
sub prefix_ap_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "access profile '" . $options{instance_value}->{display} . "' ";
|
||||
}
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
@ -93,24 +111,6 @@ sub set_counters {
|
||||
];
|
||||
}
|
||||
|
||||
sub prefix_vs_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "Virtual server '" . $options{instance_value}->{display} . "' : ";
|
||||
}
|
||||
|
||||
sub vs_long_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "checking virtual server '" . $options{instance_value}->{display} . "'";
|
||||
}
|
||||
|
||||
sub prefix_ap_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "access profile '" . $options{instance_value}->{display} . "' ";
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1, statefile => 1);
|
||||
@ -214,12 +214,54 @@ Filter virtual server name (can be a regexp).
|
||||
|
||||
Filter access profile name (can be a regexp).
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
=item B<--warning-sessions-created>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-sessions-created>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-sessions-active>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-sessions-active>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-sessions-pending>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-sessions-pending>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-ap-sessions-created>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-ap-sessions-created>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-ap-sessions-active>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-ap-sessions-active>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-ap-sessions-pending>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-ap-sessions-pending>
|
||||
|
||||
Thresholds.
|
||||
Can be: 'sessions-created', 'sessions-active', 'sessions-pending',
|
||||
'ap-sessions-created', 'ap-sessions-active', 'ap-sessions-pending'.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
=cut
|
@ -59,25 +59,37 @@ sub check {
|
||||
|
||||
$self->{components}->{fan}->{total}++;
|
||||
|
||||
$self->{output}->output_add(long_msg => sprintf("fan '%s' status is '%s' [instance: %s, speed: %s].",
|
||||
$instance, $result->{sysChassisFanStatus}, $instance,
|
||||
defined($result->{sysChassisFanSpeed}) ? $result->{sysChassisFanSpeed} : '-'));
|
||||
$self->{output}->output_add(
|
||||
long_msg => sprintf(
|
||||
"fan '%s' status is '%s' [instance: %s, speed: %s].",
|
||||
$instance, $result->{sysChassisFanStatus}, $instance,
|
||||
defined($result->{sysChassisFanSpeed}) ? $result->{sysChassisFanSpeed} : '-'
|
||||
)
|
||||
);
|
||||
|
||||
my $exit = $self->get_severity(section => 'fan', value => $result->{sysChassisFanStatus});
|
||||
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
||||
$self->{output}->output_add(severity => $exit,
|
||||
short_msg => sprintf("Fan '%s' status is '%s'",
|
||||
$instance, $result->{sysChassisFanStatus}));
|
||||
$self->{output}->output_add(
|
||||
severity => $exit,
|
||||
short_msg => sprintf(
|
||||
"Fan '%s' status is '%s'",
|
||||
$instance, $result->{sysChassisFanStatus}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (defined($result->{sysChassisFanSpeed}) && $result->{sysChassisFanSpeed} =~ /[0-9]/) {
|
||||
my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $result->{sysChassisFanSpeed});
|
||||
if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) {
|
||||
$self->{output}->output_add(severity => $exit2,
|
||||
short_msg => sprintf("fan speed '%s' is %s rpm", $instance, $result->{sysChassisFanSpeed}));
|
||||
$self->{output}->output_add(
|
||||
severity => $exit2,
|
||||
short_msg => sprintf("fan speed '%s' is %s rpm", $instance, $result->{sysChassisFanSpeed})
|
||||
);
|
||||
}
|
||||
|
||||
$self->{output}->perfdata_add(
|
||||
label => "fan", unit => 'rpm',
|
||||
nlabel => 'hardware.fan.speed.rpm',
|
||||
unit => 'rpm',
|
||||
instances => $instance,
|
||||
value => $result->{sysChassisFanSpeed},
|
||||
warning => $warn,
|
||||
|
@ -57,14 +57,22 @@ sub check {
|
||||
|
||||
$self->{components}->{psu}->{total}++;
|
||||
|
||||
$self->{output}->output_add(long_msg => sprintf("power supply '%s' status is '%s' [instance: %s].",
|
||||
$instance, $result->{sysChassisPowerSupplyStatus}, $instance
|
||||
));
|
||||
$self->{output}->output_add(
|
||||
long_msg => sprintf(
|
||||
"power supply '%s' status is '%s' [instance: %s].",
|
||||
$instance, $result->{sysChassisPowerSupplyStatus}, $instance
|
||||
)
|
||||
);
|
||||
|
||||
my $exit = $self->get_severity(section => 'psu', value => $result->{sysChassisPowerSupplyStatus});
|
||||
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
||||
$self->{output}->output_add(severity => $exit,
|
||||
short_msg => sprintf("Power supply '%s' status is '%s'",
|
||||
$instance, $result->{sysChassisPowerSupplyStatus}));
|
||||
$self->{output}->output_add(
|
||||
severity => $exit,
|
||||
short_msg => sprintf(
|
||||
"Power supply '%s' status is '%s'",
|
||||
$instance, $result->{sysChassisPowerSupplyStatus}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,19 +48,25 @@ sub check {
|
||||
next if ($self->check_filter(section => 'temperature', instance => $instance));
|
||||
|
||||
$self->{components}->{temperature}->{total}++;
|
||||
$self->{output}->output_add(long_msg => sprintf("temperature '%s' is %.2f C [instance: %s].",
|
||||
$instance, $result->{sysChassisTempTemperature}, $instance
|
||||
));
|
||||
$self->{output}->output_add(
|
||||
long_msg => sprintf(
|
||||
"temperature '%s' is %.2f C [instance: %s].",
|
||||
$instance, $result->{sysChassisTempTemperature}, $instance
|
||||
)
|
||||
);
|
||||
|
||||
if (defined($result->{sysChassisTempTemperature}) && $result->{sysChassisTempTemperature} =~ /[0-9]/) {
|
||||
my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{sysChassisTempTemperature});
|
||||
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
|
||||
$self->{output}->output_add(severity => $exit,
|
||||
short_msg => sprintf("Temperature '%s' is %.2f C", $instance, $result->{sysChassisTempTemperature}));
|
||||
$self->{output}->output_add(
|
||||
severity => $exit,
|
||||
short_msg => sprintf("Temperature '%s' is %.2f C", $instance, $result->{sysChassisTempTemperature})
|
||||
);
|
||||
}
|
||||
|
||||
$self->{output}->perfdata_add(
|
||||
label => "temp", unit => 'C',
|
||||
nlabel => 'hardware.temperature.celsius',
|
||||
unit => 'C',
|
||||
instances => $instance,
|
||||
value => sprintf("%.2f", $result->{sysChassisTempTemperature}),
|
||||
warning => $warn,
|
||||
|
@ -42,67 +42,69 @@ sub set_counters {
|
||||
$self->{maps_counters_type} = [
|
||||
{ name => 'global', type => 0 },
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{global} = [
|
||||
{ label => 'client', set => {
|
||||
{ label => 'client', nlabel => 'connections.client.current.count', set => {
|
||||
key_values => [ { name => 'client' } ],
|
||||
output_template => 'Current client connections : %s',
|
||||
perfdatas => [
|
||||
{ label => 'Client', template => '%s', min => 0, unit => 'con' },
|
||||
],
|
||||
{ template => '%s', min => 0 }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'client-ssl', set => {
|
||||
{ label => 'client-ssl', nlabel => 'connections.client.ssl.current.count', set => {
|
||||
key_values => [ { name => 'client_ssl' } ],
|
||||
output_template => 'Current client SSL connections : %s',
|
||||
perfdatas => [
|
||||
{ label => 'ClientSSL', template => '%s', min => 0, unit => 'con' },
|
||||
],
|
||||
{ template => '%s', min => 0 }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'client-ssl-tps', set => {
|
||||
{ label => 'client-ssl-tps', nlabel => 'connections.client.ssl.persecond', set => {
|
||||
key_values => [ { name => 'client_ssl_tot_native', diff => 1 }, { name => 'client_ssl_tot_compat', diff => 1 } ],
|
||||
output_template => 'TPS client SSL connections : %.2f', threshold_use => 'client_ssl_tps', output_use => 'client_ssl_tps',
|
||||
output_template => 'TPS client SSL connections : %.2f',
|
||||
threshold_use => 'client_ssl_tps',
|
||||
output_use => 'client_ssl_tps',
|
||||
closure_custom_calc => $self->can('custom_client_tps_calc'),
|
||||
perfdatas => [
|
||||
{ label => 'ClientSSL_Tps', value => 'client_ssl_tps', template => '%.2f',
|
||||
unit => 'tps', min => 0 },
|
||||
],
|
||||
{ value => 'client_ssl_tps', template => '%.2f', min => 0 }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'server', set => {
|
||||
{ label => 'server', nlabel => 'connections.server.current.count', set => {
|
||||
key_values => [ { name => 'server' } ],
|
||||
output_template => 'Current server connections: %s',
|
||||
perfdatas => [
|
||||
{ label => 'Server', template => '%s', min => 0, unit => 'con' },
|
||||
],
|
||||
{ template => '%s', min => 0 }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'server-ssl', set => {
|
||||
{ label => 'server-ssl', nlabel => 'connections.server.ssl.current.count', set => {
|
||||
key_values => [ { name => 'server_ssl' } ],
|
||||
output_template => 'Current server SSL connections : %s',
|
||||
perfdatas => [
|
||||
{ label => 'ServerSSL', template => '%s', min => 0, unit => 'con' },
|
||||
],
|
||||
{ template => '%s', min => 0 }
|
||||
]
|
||||
}
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1);
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1);
|
||||
bless $self, $class;
|
||||
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
});
|
||||
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{cache_name} = "f5_bipgip_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' .
|
||||
$self->{cache_name} = 'f5_bipgip_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' .
|
||||
(defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all'));
|
||||
|
||||
my $oid_sysStatClientCurConns = '.1.3.6.1.4.1.3375.2.1.1.2.1.8.0';
|
||||
@ -111,12 +113,12 @@ sub manage_selection {
|
||||
my $oid_sysServersslStatCurConns = '.1.3.6.1.4.1.3375.2.1.1.2.10.2.0';
|
||||
my $oid_sysClientsslStatTotNativeConns = '.1.3.6.1.4.1.3375.2.1.1.2.9.6.0';
|
||||
my $oid_sysClientsslStatTotCompatConns = '.1.3.6.1.4.1.3375.2.1.1.2.9.9.0';
|
||||
|
||||
|
||||
if ($options{snmp}->is_snmpv1()) {
|
||||
$self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3.");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
|
||||
my $result = $options{snmp}->get_leef(
|
||||
oids => [
|
||||
$oid_sysStatClientCurConns, $oid_sysStatServerCurConns,
|
||||
@ -125,13 +127,14 @@ sub manage_selection {
|
||||
],
|
||||
nothing_quit => 1
|
||||
);
|
||||
|
||||
$self->{global} = {
|
||||
client => $result->{$oid_sysStatClientCurConns},
|
||||
client_ssl => $result->{$oid_sysClientsslStatCurConns},
|
||||
client_ssl_tot_native => $result->{$oid_sysClientsslStatTotNativeConns},
|
||||
client_ssl_tot_compat => $result->{$oid_sysClientsslStatTotCompatConns},
|
||||
server => $result->{$oid_sysStatServerCurConns},
|
||||
server_ssl => $result->{$oid_sysServersslStatCurConns},
|
||||
server_ssl => $result->{$oid_sysServersslStatCurConns}
|
||||
};
|
||||
}
|
||||
|
||||
@ -150,15 +153,45 @@ Check current connections on F5 BIG IP device.
|
||||
Only display some counters (regexp can be used).
|
||||
Example to check SSL connections only : --filter-counters='^client-ssl|server-ssl$'
|
||||
|
||||
=item B<--warning-*>
|
||||
=item B<--warning-client>
|
||||
|
||||
Warning threshold.
|
||||
Can be: 'client', 'server', 'client-ssl', 'server-ssl', 'client-ssl-tps'.
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-*>
|
||||
=item B<--critical-client>
|
||||
|
||||
Critical threshold.
|
||||
Can be: 'client', 'server', 'client-ssl', 'server-ssl', 'client-ssl-tps'.
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-server>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-server>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-client-ssl>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-client-ssl>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-server-ssl>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-server-ssl>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-client-ssl-tps>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-client-ssl-tps>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=back
|
||||
|
||||
|
290
src/network/f5/bigip/snmp/mode/cpuusage.pm
Normal file
290
src/network/f5/bigip/snmp/mode/cpuusage.pm
Normal file
@ -0,0 +1,290 @@
|
||||
#
|
||||
# Copyright 2025 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
# service performance.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
package network::f5::bigip::snmp::mode::cpuusage;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Digest::MD5 qw(md5_hex);
|
||||
|
||||
sub custom_usage_perfdata {
|
||||
my ($self, %options) = @_;
|
||||
}
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{ name => 'cpu', type => 1, cb_prefix_output => 'prefix_cpu_output', message_multiple => 'All CPU are ok', skipped_code => { -10 => 1 } },
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{cpu} = [
|
||||
{ label => 'usage-5s', set => {
|
||||
key_values => [ { name => 'sysMultiHostCpuUsageRatio5s' }, { name => 'display' } ],
|
||||
output_template => 'CPU Usage 5sec : %s %%', output_error_template => "CPU Usage 5sec : %s",
|
||||
perfdatas => [
|
||||
{ label => 'usage_5s', value => 'sysMultiHostCpuUsageRatio5s', template => '%s',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
}
|
||||
},
|
||||
{ label => 'usage-1m', set => {
|
||||
key_values => [ { name => 'sysMultiHostCpuUsageRatio1m' }, { name => 'display' } ],
|
||||
output_template => 'CPU Usage 1min : %s %%', output_error_template => "CPU Usage 1min : %s",
|
||||
perfdatas => [
|
||||
{ label => 'usage_1m', value => 'sysMultiHostCpuUsageRatio1m', template => '%s',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
}
|
||||
},
|
||||
{ label => 'usage-5m', set => {
|
||||
key_values => [ { name => 'sysMultiHostCpuUsageRatio5m' }, { name => 'display' } ],
|
||||
output_template => 'CPU Usage 5min : %s %%', output_error_template => "CPU Usage 5min : %s",
|
||||
perfdatas => [
|
||||
{ label => 'usage_5m', value => 'sysMultiHostCpuUsageRatio5m', template => '%s',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
}
|
||||
},
|
||||
{ label => 'user-5s', set => {
|
||||
key_values => [ { name => 'sysMultiHostCpuUser5s' }, { name => 'display' } ],
|
||||
output_template => 'CPU User 5sec : %s %%', output_error_template => "CPU User 5sec : %s",
|
||||
perfdatas => [
|
||||
{ label => 'user_5s', value => 'sysMultiHostCpuUser5s', template => '%s',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
}
|
||||
},
|
||||
{ label => 'user-1m', set => {
|
||||
key_values => [ { name => 'sysMultiHostCpuUser1m' }, { name => 'display' } ],
|
||||
output_template => 'CPU User 1min : %s %%', output_error_template => "CPU User 1min : %s",
|
||||
perfdatas => [
|
||||
{ label => 'user_1m', value => 'sysMultiHostCpuUser1m', template => '%s',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
}
|
||||
},
|
||||
{ label => 'user-5m', set => {
|
||||
key_values => [ { name => 'sysMultiHostCpuUser5m' }, { name => 'display' } ],
|
||||
output_template => 'CPU User 5min : %s %%', output_error_template => "CPU User 5min : %s",
|
||||
perfdatas => [
|
||||
{ label => 'user_5m', value => 'sysMultiHostCpuUser5m', template => '%s',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
}
|
||||
},
|
||||
{ label => 'iowait-5s', set => {
|
||||
key_values => [ { name => 'sysMultiHostCpuIowait5s' }, { name => 'display' } ],
|
||||
output_template => 'CPU IO Wait 5sec : %s %%', output_error_template => "CPU IO Wait 5sec : %s",
|
||||
perfdatas => [
|
||||
{ label => 'iowait_5s', value => 'sysMultiHostCpuIowait5s', template => '%s',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
}
|
||||
},
|
||||
{ label => 'iowait-1m', set => {
|
||||
key_values => [ { name => 'sysMultiHostCpuIowait1m' }, { name => 'display' } ],
|
||||
output_template => 'CPU IO Wait 1min : %s %%', output_error_template => "CPU IO Wait 1min : %s",
|
||||
perfdatas => [
|
||||
{ label => 'iowait_1m', value => 'sysMultiHostCpuIowait1m', template => '%s',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
}
|
||||
},
|
||||
{ label => 'iowait-5m', set => {
|
||||
key_values => [ { name => 'sysMultiHostCpuIowait5m' }, { name => 'display' } ],
|
||||
output_template => 'CPU IO Wait 5min : %s %%', output_error_template => "CPU IO Wait 5min : %s",
|
||||
perfdatas => [
|
||||
{ label => 'iowait_5m', value => 'sysMultiHostCpuIowait5m', template => '%s',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
}
|
||||
},
|
||||
{ label => 'system-5s', set => {
|
||||
key_values => [ { name => 'sysMultiHostCpuSystem5s' }, { name => 'display' } ],
|
||||
output_template => 'CPU System 5sec : %s %%', output_error_template => "CPU System 5sec : %s",
|
||||
perfdatas => [
|
||||
{ label => 'system_5s', value => 'sysMultiHostCpuSystem5s', template => '%s',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
}
|
||||
},
|
||||
{ label => 'system-1m', set => {
|
||||
key_values => [ { name => 'sysMultiHostCpuSystem1m' }, { name => 'display' } ],
|
||||
output_template => 'CPU System 1min : %s %%', output_error_template => "CPU System 1min : %s",
|
||||
perfdatas => [
|
||||
{ label => 'system_1m', value => 'sysMultiHostCpuSystem1m', template => '%s',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
}
|
||||
},
|
||||
{ label => 'system-5m', set => {
|
||||
key_values => [ { name => 'sysMultiHostCpuSystem5m' }, { name => 'display' } ],
|
||||
output_template => 'CPU System 5min : %s %%', output_error_template => "CPU System 5min : %s",
|
||||
perfdatas => [
|
||||
{ label => 'system_5m', value => 'sysMultiHostCpuSystem5m', template => '%s',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
}
|
||||
},
|
||||
{ label => 'idle-5s', set => {
|
||||
key_values => [ { name => 'sysMultiHostCpuIdle5s' }, { name => 'display' } ],
|
||||
output_template => 'CPU Idle 5sec : %s %%', output_error_template => "CPU Idle 5sec : %s",
|
||||
perfdatas => [
|
||||
{ label => 'idle_5s', value => 'sysMultiHostCpuIdle5s', template => '%s',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
}
|
||||
},
|
||||
{ label => 'idle-1m', set => {
|
||||
key_values => [ { name => 'sysMultiHostCpuIdle1m' }, { name => 'display' } ],
|
||||
output_template => 'CPU Idle 1min : %s %%', output_error_template => "CPU Idle 1min : %s",
|
||||
perfdatas => [
|
||||
{ label => 'idle_1m', value => 'sysMultiHostCpuIdle1m', template => '%s',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
}
|
||||
},
|
||||
{ label => 'idle-5m', set => {
|
||||
key_values => [ { name => 'sysMultiHostCpuIdle5m' }, { name => 'display' } ],
|
||||
output_template => 'CPU Idle 5min : %s %%', output_error_template => "CPU Idle 5min : %s",
|
||||
perfdatas => [
|
||||
{ label => 'idle_5m', value => 'sysMultiHostCpuIdle5m', template => '%s',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
}
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
sub prefix_cpu_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "CPU '" . $options{instance_value}->{display} . "' ";
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
'filter-name:s' => { name => 'filter_name' },
|
||||
});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
my $mapping = {
|
||||
sysMultiHostCpuId => { oid => '.1.3.6.1.4.1.3375.2.1.7.5.2.1.3' },
|
||||
sysMultiHostCpuUsageRatio5s => { oid => '.1.3.6.1.4.1.3375.2.1.7.5.2.1.19' },
|
||||
sysMultiHostCpuUsageRatio1m => { oid => '.1.3.6.1.4.1.3375.2.1.7.5.2.1.27' },
|
||||
sysMultiHostCpuUsageRatio5m => { oid => '.1.3.6.1.4.1.3375.2.1.7.5.2.1.35' },
|
||||
sysMultiHostCpuUser5s => { oid => '.1.3.6.1.4.1.3375.2.1.7.5.2.1.12' },
|
||||
sysMultiHostCpuUser1m => { oid => '.1.3.6.1.4.1.3375.2.1.7.5.2.1.20' },
|
||||
sysMultiHostCpuUser5m => { oid => '.1.3.6.1.4.1.3375.2.1.7.5.2.1.28' },
|
||||
sysMultiHostCpuIowait5s => { oid => '.1.3.6.1.4.1.3375.2.1.7.5.2.1.18' },
|
||||
sysMultiHostCpuIowait1m => { oid => '.1.3.6.1.4.1.3375.2.1.7.5.2.1.26' },
|
||||
sysMultiHostCpuIowait5m => { oid => '.1.3.6.1.4.1.3375.2.1.7.5.2.1.34' },
|
||||
sysMultiHostCpuSystem5s => { oid => '.1.3.6.1.4.1.3375.2.1.7.5.2.1.14' },
|
||||
sysMultiHostCpuSystem1m => { oid => '.1.3.6.1.4.1.3375.2.1.7.5.2.1.22' },
|
||||
sysMultiHostCpuSystem5m => { oid => '.1.3.6.1.4.1.3375.2.1.7.5.2.1.30' },
|
||||
sysMultiHostCpuIdle5s => { oid => '.1.3.6.1.4.1.3375.2.1.7.5.2.1.15' },
|
||||
sysMultiHostCpuIdle1m => { oid => '.1.3.6.1.4.1.3375.2.1.7.5.2.1.23' },
|
||||
sysMultiHostCpuIdle5m => { oid => '.1.3.6.1.4.1.3375.2.1.7.5.2.1.31' },
|
||||
};
|
||||
my $oid_sysMultiHostCpuEntry = '.1.3.6.1.4.1.3375.2.1.7.5.2.1';
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
if ($options{snmp}->is_snmpv1()) {
|
||||
$self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3.");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
my $results = $options{snmp}->get_table(
|
||||
oid => $oid_sysMultiHostCpuEntry,
|
||||
nothing_quit => 1
|
||||
);
|
||||
|
||||
$self->{cpu} = {};
|
||||
foreach my $oid (keys %$results) {
|
||||
next if ($oid !~ /^$mapping->{sysMultiHostCpuId}->{oid}\.(.*)$/);
|
||||
my $instance = $1;
|
||||
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance);
|
||||
|
||||
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
|
||||
$result->{sysMultiHostCpuId} !~ /$self->{option_results}->{filter_name}/) {
|
||||
$self->{output}->output_add(long_msg => "skipping '" . $result->{sysMultiHostCpuId} . "': no matching filter name.", debug => 1);
|
||||
next;
|
||||
}
|
||||
|
||||
$self->{cpu}->{$result->{sysMultiHostCpuId}} = {
|
||||
display => $result->{sysMultiHostCpuId},
|
||||
%$result
|
||||
};
|
||||
}
|
||||
|
||||
if (scalar(keys %{$self->{cpu}}) <= 0) {
|
||||
$self->{output}->add_option_msg(short_msg => "No CPU found.");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
$self->{cache_name} = "f5_bipgip_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' .
|
||||
(defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')) . '_' .
|
||||
(defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all'));
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check CPU usages.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--filter-counters>
|
||||
|
||||
Only display some counters (regexp can be used).
|
||||
Example : --filter-counters='^usage$'
|
||||
|
||||
=item B<--filter-name>
|
||||
|
||||
Filter by CPU id (regexp can be used).
|
||||
Example : --filter-name='2'
|
||||
|
||||
=item B<--warning-*>
|
||||
|
||||
Warning threshold.
|
||||
Can be: 'usage-1m', 'usage-5m', 'iowait-5s'.
|
||||
|
||||
=item B<--critical-*>
|
||||
|
||||
Critical threshold.
|
||||
Can be: 'usage-1m', 'usage-5m', 'iowait-5s'.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
@ -24,7 +24,19 @@ use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold);
|
||||
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
|
||||
|
||||
sub custom_syncstatus_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "Sync status is '" . $self->{result_values}->{syncstatus} . "'";
|
||||
}
|
||||
|
||||
sub custom_failoverstatus_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "Failover status is '" . $self->{result_values}->{failoverstatus} . "'";
|
||||
}
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
@ -34,78 +46,36 @@ sub set_counters {
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{global} = [
|
||||
{ label => 'sync-status', threshold => 0, set => {
|
||||
{ label => 'sync-status', type => 2, critical_default => '%{syncstatus} =~ /unknown|syncFailed|syncDisconnected|incompatibleVersion/', set => {
|
||||
key_values => [ { name => 'syncstatus' } ],
|
||||
closure_custom_calc => \&custom_syncstatus_calc,
|
||||
closure_custom_output => \&custom_syncstatus_output,
|
||||
closure_custom_perfdata => sub { return 0; },
|
||||
closure_custom_threshold_check => \&catalog_status_threshold,
|
||||
closure_custom_threshold_check => \&catalog_status_threshold_ng
|
||||
}
|
||||
},
|
||||
{ label => 'failover-status', threshold => 0, set => {
|
||||
{ label => 'failover-status', type => 2, critical_default => '%{failoverstatus} =~ /unknown/', set => {
|
||||
key_values => [ { name => 'failoverstatus' } ],
|
||||
closure_custom_calc => \&custom_failoverstatus_calc,
|
||||
closure_custom_output => \&custom_failoverstatus_output,
|
||||
closure_custom_perfdata => sub { return 0; },
|
||||
closure_custom_threshold_check => \&catalog_status_threshold,
|
||||
closure_custom_threshold_check => \&catalog_status_threshold_ng
|
||||
}
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
sub custom_syncstatus_output {
|
||||
my ($self, %options) = @_;
|
||||
my $msg = "Sync status is '" . $self->{result_values}->{syncstatus} . "'";
|
||||
|
||||
return $msg;
|
||||
}
|
||||
|
||||
sub custom_syncstatus_calc {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{result_values}->{syncstatus} = $options{new_datas}->{$self->{instance} . '_syncstatus'};
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub custom_failoverstatus_output {
|
||||
my ($self, %options) = @_;
|
||||
my $msg = "Failover status is '" . $self->{result_values}->{failoverstatus} . "'";
|
||||
|
||||
return $msg;
|
||||
}
|
||||
|
||||
sub custom_failoverstatus_calc {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{result_values}->{failoverstatus} = $options{new_datas}->{$self->{instance} . '_failoverstatus'};
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
'warning-sync-status:s' => { name => 'warning_sync_status', default => '' },
|
||||
'critical-sync-status:s' => { name => 'critical_sync_status', default => '%{syncstatus} =~ /unknown|syncFailed|syncDisconnected|incompatibleVersion/' },
|
||||
'warning-failover-status:s' => { name => 'warning_failover_status', default => '' },
|
||||
'critical-failover-status:s' => { name => 'critical_failover_status', default => '%{failoverstatus} =~ /unknown/' },
|
||||
});
|
||||
$options{options}->add_options(arguments => {});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
$self->change_macros(macros => ['warning_sync_status', 'critical_sync_status', 'warning_failover_status', 'critical_failover_status']);
|
||||
}
|
||||
|
||||
my %map_boolean = (
|
||||
0 => 'false',
|
||||
1 => 'true',
|
||||
1 => 'true'
|
||||
);
|
||||
my %map_sync_status = (
|
||||
0 => 'unknown',
|
||||
@ -117,21 +87,21 @@ my %map_sync_status = (
|
||||
6 => 'standalone',
|
||||
7 => 'awaitingInitialSync',
|
||||
8 => 'incompatibleVersion',
|
||||
9 => 'partialSync',
|
||||
9 => 'partialSync'
|
||||
);
|
||||
my %map_failover_status = (
|
||||
0 => 'unknown',
|
||||
1 => 'offline',
|
||||
2 => 'forcedOffline',
|
||||
3 => 'standby',
|
||||
4 => 'active',
|
||||
4 => 'active'
|
||||
);
|
||||
|
||||
my $mapping = {
|
||||
sysAttrFailoverIsRedundant => { oid => '.1.3.6.1.4.1.3375.2.1.1.1.1.13', map => \%map_boolean },
|
||||
sysAttrModeMaint => { oid => '.1.3.6.1.4.1.3375.2.1.1.1.1.21', map => \%map_boolean },
|
||||
sysCmSyncStatusId => { oid => '.1.3.6.1.4.1.3375.2.1.14.1.1', map => \%map_sync_status },
|
||||
sysCmFailoverStatusId => { oid => '.1.3.6.1.4.1.3375.2.1.14.3.1', map => \%map_failover_status },
|
||||
sysCmFailoverStatusId => { oid => '.1.3.6.1.4.1.3375.2.1.14.3.1', map => \%map_failover_status }
|
||||
};
|
||||
|
||||
sub manage_selection {
|
||||
@ -164,7 +134,7 @@ sub manage_selection {
|
||||
$self->{output}->display();
|
||||
$self->{output}->exit();
|
||||
}
|
||||
|
||||
|
||||
$self->{global} = {
|
||||
syncstatus => $result->{sysCmSyncStatusId},
|
||||
failoverstatus => $result->{sysCmFailoverStatusId},
|
||||
@ -187,22 +157,22 @@ Only display some counters (regexp can be used).
|
||||
|
||||
=item B<--warning-sync-status>
|
||||
|
||||
Set warning threshold for sync status
|
||||
Define the conditions to match for the status to be WARNING.
|
||||
You can use the following variables: %{syncstatus}
|
||||
|
||||
=item B<--critical-sync-status>
|
||||
|
||||
Set critical threshold for sync status (default: '%{syncstatus} =~ /unknown|syncFailed|syncDisconnected|incompatibleVersion/').
|
||||
Define the conditions to match for the status to be CRITICAL (default: '%{syncstatus} =~ /unknown|syncFailed|syncDisconnected|incompatibleVersion/').
|
||||
You can use the following variables: %{syncstatus}
|
||||
|
||||
=item B<--warning-failover-status>
|
||||
|
||||
Set warning threshold for failover status
|
||||
Define the conditions to match for the status to be WARNING.
|
||||
You can use the following variables: %{failoverstatus}
|
||||
|
||||
=item B<--critical-failover-status>
|
||||
|
||||
Set critical threshold for failover status (default: '%{failoverstatus} =~ /unknown/').
|
||||
Define the conditions to match for the status to be CRITICAL (Default: '%{failoverstatus} =~ /unknown/').
|
||||
You can use the following variables: %{failoverstatus}
|
||||
|
||||
=back
|
||||
|
@ -58,7 +58,7 @@ sub snmp_execute {
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {});
|
||||
|
@ -103,8 +103,10 @@ sub run {
|
||||
);
|
||||
}
|
||||
|
||||
$self->{output}->output_add(severity => 'OK',
|
||||
short_msg => 'List nodes:');
|
||||
$self->{output}->output_add(
|
||||
severity => 'OK',
|
||||
short_msg => 'List nodes:'
|
||||
);
|
||||
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
|
||||
$self->{output}->exit();
|
||||
}
|
||||
|
@ -106,8 +106,10 @@ sub run {
|
||||
);
|
||||
}
|
||||
|
||||
$self->{output}->output_add(severity => 'OK',
|
||||
short_msg => 'List pools:');
|
||||
$self->{output}->output_add(
|
||||
severity => 'OK',
|
||||
short_msg => 'List pools:'
|
||||
);
|
||||
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
|
||||
$self->{output}->exit();
|
||||
}
|
||||
|
@ -122,8 +122,10 @@ sub run {
|
||||
);
|
||||
}
|
||||
|
||||
$self->{output}->output_add(severity => 'OK',
|
||||
short_msg => 'List virtual servers:');
|
||||
$self->{output}->output_add(
|
||||
severity => 'OK',
|
||||
short_msg => 'List virtual servers:'
|
||||
);
|
||||
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
|
||||
$self->{output}->exit();
|
||||
}
|
||||
|
@ -64,12 +64,11 @@ sub set_counters {
|
||||
closure_custom_threshold_check => \&catalog_status_threshold_ng
|
||||
}
|
||||
},
|
||||
{ label => 'current-server-connections', set => {
|
||||
{ label => 'current-server-connections', nlabel => 'node.connections.server.current.count', set => {
|
||||
key_values => [ { name => 'ltmNodeAddrStatServerCurConns' }, { name => 'display' } ],
|
||||
output_template => 'current server connections : %s',
|
||||
perfdatas => [
|
||||
{ label => 'current_server_connections', template => '%s',
|
||||
min => 0, label_extra_instance => 1, instance_use => 'display' }
|
||||
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'display' }
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -78,7 +77,7 @@ sub set_counters {
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
@ -135,7 +134,7 @@ sub manage_selection {
|
||||
foreach my $oid (keys %{$snmp_result->{$branch_name}}) {
|
||||
$oid =~ /^$branch_name\.(.*?)\.(.*)$/;
|
||||
my ($num, $index) = ($1, $2);
|
||||
|
||||
|
||||
my $result = $options{snmp}->map_instance(mapping => $mapping->{$map}, results => $snmp_result->{$branch_name}, instance => $num . '.' . $index);
|
||||
my $name = $self->{output}->decode(join('', map(chr($_), split(/\./, $index))));
|
||||
|
||||
@ -207,10 +206,13 @@ You can use the following variables: %{state}, %{status}, %{display}
|
||||
Define the conditions to match for the status to be CRITICAL (default: '%{state} eq "enabled" and %{status} eq "red"').
|
||||
You can use the following variables: %{state}, %{status}, %{display}
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
=item B<--warning-current-server-connections>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-current-server-connections>
|
||||
|
||||
Thresholds.
|
||||
Can be: 'current-server-connections'.
|
||||
|
||||
=back
|
||||
|
||||
|
@ -91,7 +91,7 @@ sub set_counters {
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{pool_connections} = [
|
||||
{ label => 'current-server-connections', nlabel => 'pool.connections.server.count', set => {
|
||||
{ label => 'current-server-connections', nlabel => 'pool.connections.server.current.count', set => {
|
||||
key_values => [ { name => 'ltmPoolStatServerCurConns' }, { name => 'display' } ],
|
||||
output_template => 'current server connections: %s',
|
||||
perfdatas => [
|
||||
@ -360,10 +360,29 @@ You can use the following variables: %{state}, %{status}, %{poolName}, %{nodeNam
|
||||
Define the conditions to match for the status to be CRITICAL.
|
||||
You can use the following variables: %{state}, %{status}, %{poolName}, %{nodeName}
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
=item B<--warning-current-server-connections>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-current-server-connections>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-current-active-members>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-current-active-members>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-current-total-members>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-current-total-members>
|
||||
|
||||
Thresholds.
|
||||
Can be: 'current-server-connections', 'current-active-members', 'current-total-members'.
|
||||
|
||||
=back
|
||||
|
||||
|
@ -30,8 +30,9 @@ sub custom_usage_perfdata {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{output}->perfdata_add(
|
||||
label => 'memory_used', unit => 'B',
|
||||
instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef,
|
||||
nlabel => $self->{nlabel},
|
||||
unit => 'B',
|
||||
instances => $self->{result_values}->{display},
|
||||
value => $self->{result_values}->{used},
|
||||
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1),
|
||||
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1),
|
||||
@ -53,11 +54,12 @@ sub custom_usage_output {
|
||||
my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used});
|
||||
my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free});
|
||||
|
||||
my $msg = sprintf("Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)",
|
||||
$total_size_value . " " . $total_size_unit,
|
||||
$total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used},
|
||||
$total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free});
|
||||
return $msg;
|
||||
return sprintf(
|
||||
"Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)",
|
||||
$total_size_value . " " . $total_size_unit,
|
||||
$total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used},
|
||||
$total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}
|
||||
);
|
||||
}
|
||||
|
||||
sub custom_usage_calc {
|
||||
@ -73,6 +75,12 @@ sub custom_usage_calc {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub prefix_tmm_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "TMM '" . $options{instance_value}->{display} . "' ";
|
||||
}
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
@ -81,84 +89,73 @@ sub set_counters {
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{tmm} = [
|
||||
{ label => 'memory-usage', set => {
|
||||
{ label => 'memory-usage', nlabel => 'tmm.memory.usage.bytes', set => {
|
||||
key_values => [ { name => 'display' }, { name => 'sysTmmStatMemoryTotal' }, { name => 'sysTmmStatMemoryUsed' } ],
|
||||
closure_custom_calc => $self->can('custom_usage_calc'),
|
||||
closure_custom_output => $self->can('custom_usage_output'),
|
||||
closure_custom_perfdata => $self->can('custom_usage_perfdata'),
|
||||
closure_custom_threshold_check => $self->can('custom_usage_threshold'),
|
||||
closure_custom_threshold_check => $self->can('custom_usage_threshold')
|
||||
}
|
||||
},
|
||||
{ label => 'cpu-1m', set => {
|
||||
{ label => 'cpu-1m', nlabel => 'tmm.cpu.utilization.1m.percentage', set => {
|
||||
key_values => [ { name => 'sysTmmStatTmUsageRatio1m' }, { name => 'display' } ],
|
||||
output_template => 'CPU Usage 1min : %s %%', output_error_template => "CPU Usage 1min : %s",
|
||||
perfdatas => [
|
||||
{ label => 'cpu_1m', value => 'sysTmmStatTmUsageRatio1m', template => '%s',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
{ template => '%s', unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'cpu-5m', set => {
|
||||
{ label => 'cpu-5m', nlabel => 'tmm.cpu.utilization.5m.percentage', set => {
|
||||
key_values => [ { name => 'sysTmmStatTmUsageRatio5m' }, { name => 'display' } ],
|
||||
output_template => 'CPU Usage 5min : %s %%', output_error_template => "CPU Usage 5min : %s",
|
||||
perfdatas => [
|
||||
{ label => 'cpu_5m', value => 'sysTmmStatTmUsageRatio5m', template => '%s',
|
||||
unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
{ template => '%s', unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'current-client-connections', set => {
|
||||
{ label => 'current-client-connections', nlabel => 'tmm.connections.client.curent.count', set => {
|
||||
key_values => [ { name => 'sysTmmStatClientCurConns' }, { name => 'display' } ],
|
||||
output_template => 'Current Client Connections : %s', output_error_template => "Current Client Connections : %s",
|
||||
perfdatas => [
|
||||
{ label => 'current_client_connections', value => 'sysTmmStatClientCurConns', template => '%s',
|
||||
min => 0, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
{ label => 'current_client_connections', template => '%s',
|
||||
min => 0, label_extra_instance => 1, instance_use => 'display' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'total-client-connections', set => {
|
||||
{ label => 'total-client-connections', nlabel => 'tmm.connections.client.total.count', set => {
|
||||
key_values => [ { name => 'sysTmmStatClientTotConns', diff => 1 }, { name => 'display' } ],
|
||||
output_template => 'Total Client Connections : %s', output_error_template => "Total Client Connections : %s",
|
||||
perfdatas => [
|
||||
{ label => 'total_client_connections', value => 'sysTmmStatClientTotConns', template => '%s',
|
||||
min => 0, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'display' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'current-server-connections', set => {
|
||||
{ label => 'current-server-connections', nlabel => 'tmm.connections.server.current.count', set => {
|
||||
key_values => [ { name => 'sysTmmStatServerCurConns' }, { name => 'display' } ],
|
||||
output_template => 'Current Server Connections : %s', output_error_template => "Current Server Connections : %s",
|
||||
perfdatas => [
|
||||
{ label => 'current_server_connections', value => 'sysTmmStatServerCurConns', template => '%s',
|
||||
min => 0, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'display' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ label => 'total-server-connections', set => {
|
||||
{ label => 'total-server-connections', nlabel => 'tmm.connections.server.total.count', set => {
|
||||
key_values => [ { name => 'sysTmmStatServerTotConns', diff => 1 }, { name => 'display' } ],
|
||||
output_template => 'Total Server Connections : %s', output_error_template => "Total Server Connections : %s",
|
||||
perfdatas => [
|
||||
{ label => 'total_server_connections', value => 'sysTmmStatServerTotConns', template => '%s',
|
||||
min => 0, label_extra_instance => 1, instance_use => 'display' },
|
||||
],
|
||||
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'display' }
|
||||
]
|
||||
}
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
sub prefix_tmm_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "TMM '" . $options{instance_value}->{display} . "' ";
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1);
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
'filter-name:s' => { name => 'filter_name' },
|
||||
'filter-name:s' => { name => 'filter_name' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
@ -207,12 +204,12 @@ sub manage_selection {
|
||||
%$result
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
if (scalar(keys %{$self->{tmm}}) <= 0) {
|
||||
$self->{output}->add_option_msg(short_msg => "No TMM found.");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
|
||||
$self->{cache_name} = "f5_bipgip_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' .
|
||||
(defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')) . '_' .
|
||||
(defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all'));
|
||||
@ -224,7 +221,7 @@ __END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check TMM usages.
|
||||
Check TMM (Traffic Management Microkernel) usages.
|
||||
|
||||
=over 8
|
||||
|
||||
@ -235,19 +232,63 @@ Example : --filter-counters='^memory-usage$'
|
||||
|
||||
=item B<--filter-name>
|
||||
|
||||
Filter by TMM name (regexp can be used).
|
||||
Filter by TMM (Traffic Management Microkernel) name (regexp can be used).
|
||||
|
||||
=item B<--warning-*>
|
||||
=item B<--warning-cpu-1m>
|
||||
|
||||
Warning threshold.
|
||||
Can be: 'cpu-1m', 'cpu-5m', 'memory-usage' (%), 'total-client-connections', 'current-client-connections',
|
||||
'total-server-connections', 'current-server-connections'.
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-*>
|
||||
=item B<--critical-cpu-1m>
|
||||
|
||||
Critical threshold.
|
||||
Can be: 'cpu-1m', 'cpu-5m', 'memory-usage' (%), 'total-client-connections', 'current-client-connections',
|
||||
'total-server-connections', 'current-server-connections'.
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-cpu-5m>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-cpu-5m>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-memory-usage>
|
||||
|
||||
Thresholds in %.
|
||||
|
||||
=item B<--critical-memory-usage>
|
||||
|
||||
Thresholds in %.
|
||||
|
||||
=item B<--warning-total-client-connections>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-total-client-connections>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-current-client-connections>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-current-client-connections>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-total-server-connections>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-total-server-connections>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-current-server-connections>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-current-server-connections>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=back
|
||||
|
||||
|
@ -42,8 +42,9 @@ sub custom_traffic_perfdata {
|
||||
my $speed = $self->{result_values}->{speed} > 0 ? $self->{result_values}->{speed} : undef;
|
||||
|
||||
$self->{output}->perfdata_add(
|
||||
label => 'traffic_' . $self->{result_values}->{label}, unit => 'b/s',
|
||||
instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef,
|
||||
nlabel => $self->{nlabel},
|
||||
unit => 'b/s',
|
||||
instances => $self->{result_values}->{display},
|
||||
value => sprintf("%.2f", $self->{result_values}->{traffic_per_seconds}),
|
||||
warning => $warning,
|
||||
critical => $critical,
|
||||
@ -101,8 +102,9 @@ sub custom_errors_perfdata {
|
||||
my $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel});
|
||||
|
||||
$self->{output}->perfdata_add(
|
||||
label => 'packets_error_' . $self->{result_values}->{label}, unit => '%',
|
||||
instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef,
|
||||
nlabel => $self->{nlabel},
|
||||
unit => '%',
|
||||
instances => $self->{result_values}->{display},
|
||||
value => sprintf("%.2f", $self->{result_values}->{errors_prct}),
|
||||
warning => $warning,
|
||||
critical => $critical,
|
||||
@ -150,8 +152,9 @@ sub custom_drops_perfdata {
|
||||
my $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel});
|
||||
|
||||
$self->{output}->perfdata_add(
|
||||
label => 'packets_drop_' . $self->{result_values}->{label}, unit => '%',
|
||||
instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef,
|
||||
nlabel => $self->{nlabel},
|
||||
unit => '%',
|
||||
instances => $self->{result_values}->{display},
|
||||
value => sprintf("%.2f", $self->{result_values}->{drops_prct}),
|
||||
warning => $warning,
|
||||
critical => $critical,
|
||||
@ -233,7 +236,7 @@ sub set_counters {
|
||||
closure_custom_threshold_check => \&catalog_status_threshold_ng
|
||||
}
|
||||
},
|
||||
{ label => 'traffic-in', set => {
|
||||
{ label => 'traffic-in', nlabel => 'trunk.traffic.in.bitspersecond', set => {
|
||||
key_values => [ { name => 'sysTrunkStatBytesIn', diff => 1 }, { name => 'sysTrunkOperBw', diff => 1 }, { name => 'display' } ],
|
||||
closure_custom_calc => $self->can('custom_traffic_calc'),
|
||||
closure_custom_calc_extra_options => { label_ref => 'sysTrunkStatBytesIn', speed => 'sysTrunkOperBw', label => 'in' },
|
||||
@ -242,7 +245,7 @@ sub set_counters {
|
||||
closure_custom_threshold_check => $self->can('custom_traffic_threshold')
|
||||
}
|
||||
},
|
||||
{ label => 'traffic-out', set => {
|
||||
{ label => 'traffic-out', nlabel => 'trunk.traffic.out.bitspersecond', set => {
|
||||
key_values => [ { name => 'sysTrunkStatBytesOut', diff => 1 }, { name => 'sysTrunkOperBw', diff => 1 }, { name => 'display' } ],
|
||||
closure_custom_calc => $self->can('custom_traffic_calc'),
|
||||
closure_custom_calc_extra_options => { label_ref => 'sysTrunkStatBytesOut', speed => 'sysTrunkOperBw', label => 'out' },
|
||||
@ -251,7 +254,7 @@ sub set_counters {
|
||||
closure_custom_threshold_check => $self->can('custom_traffic_threshold')
|
||||
}
|
||||
},
|
||||
{ label => 'packets-error-in', set => {
|
||||
{ label => 'packets-error-in', nlabel => 'trunk.packets.in.error.percentage', set => {
|
||||
key_values => [ { name => 'sysTrunkStatErrorsIn', diff => 1 }, { name => 'sysTrunkStatPktsIn', diff => 1 }, { name => 'display' } ],
|
||||
closure_custom_calc => $self->can('custom_errors_calc'),
|
||||
closure_custom_calc_extra_options => { errors => 'sysTrunkStatErrorsIn', packets => 'sysTrunkStatPktsIn', label => 'in' },
|
||||
@ -260,7 +263,7 @@ sub set_counters {
|
||||
closure_custom_threshold_check => $self->can('custom_errors_threshold')
|
||||
}
|
||||
},
|
||||
{ label => 'packets-error-out', set => {
|
||||
{ label => 'packets-error-out', nlabel => 'trunk.packets.out.error.percentage', set => {
|
||||
key_values => [ { name => 'sysTrunkStatErrorsOut', diff => 1 }, { name => 'sysTrunkStatPktsOut', diff => 1 }, { name => 'display' } ],
|
||||
closure_custom_calc => $self->can('custom_errors_calc'),
|
||||
closure_custom_calc_extra_options => { errors => 'sysTrunkStatErrorsOut', packets => 'sysTrunkStatPktsOut', label => 'out' },
|
||||
@ -269,7 +272,7 @@ sub set_counters {
|
||||
closure_custom_threshold_check => $self->can('custom_errors_threshold')
|
||||
}
|
||||
},
|
||||
{ label => 'packets-drop-in', set => {
|
||||
{ label => 'packets-drop-in', nlabel => 'trunk.packets.in.dropped.percentage', set => {
|
||||
key_values => [ { name => 'sysTrunkStatDropsIn', diff => 1 }, { name => 'sysTrunkStatPktsIn', diff => 1 }, { name => 'display' } ],
|
||||
closure_custom_calc => $self->can('custom_drops_calc'),
|
||||
closure_custom_calc_extra_options => { drops => 'sysTrunkStatDropsIn', packets => 'sysTrunkStatPktsIn', label => 'in' },
|
||||
@ -278,7 +281,7 @@ sub set_counters {
|
||||
closure_custom_threshold_check => $self->can('custom_drops_threshold')
|
||||
}
|
||||
},
|
||||
{ label => 'packets-drop-out', set => {
|
||||
{ label => 'packets-drop-out', nlabel => 'trunk.packets.out.dropped.percentage', set => {
|
||||
key_values => [ { name => 'sysTrunkStatDropsOut', diff => 1 }, { name => 'sysTrunkStatPktsOut', diff => 1 }, { name => 'display' } ],
|
||||
closure_custom_calc => $self->can('custom_drops_calc'),
|
||||
closure_custom_calc_extra_options => { drops => 'sysTrunkStatDropsOut', packets => 'sysTrunkStatPktsOut', label => 'out' },
|
||||
@ -291,7 +294,7 @@ sub set_counters {
|
||||
key_values => [ { name => 'total_interfaces' }, { name => 'display' } ],
|
||||
output_template => 'total interfaces: %s',
|
||||
perfdatas => [
|
||||
{ label => 'total_interfaces', template => '%d', min => 0, label_extra_instance => 1 }
|
||||
{ template => '%d', min => 0, label_extra_instance => 1 }
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -310,7 +313,7 @@ sub set_counters {
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1);
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
@ -465,8 +468,8 @@ Units of thresholds for the traffic (default: '%') ('%', 'b/s').
|
||||
|
||||
=item B<--speed>
|
||||
|
||||
Set trunk speed in Mbps (default: sysTrunkOperBw).
|
||||
If not set and sysTrunkOperBw OID value is 0,
|
||||
Set trunk speed in Mbps (default: C<sysTrunkOperBw>).
|
||||
If not set and C<sysTrunkOperBw> OID value is 0,
|
||||
percentage thresholds will not be applied on traffic metrics.
|
||||
|
||||
=item B<--add-interfaces>
|
||||
@ -503,12 +506,61 @@ You can use the following variables: %{status}, %{display}
|
||||
Define the conditions to match for the status to be CRITICAL.
|
||||
You can use the following variables: %{status}, %{display}
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
=item B<--warning-traffic-in>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-traffic-in>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-traffic-out>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-traffic-out>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--warning-packets-error-in>
|
||||
|
||||
Thresholds in %.
|
||||
|
||||
=item B<--critical-packets-error-in>
|
||||
|
||||
Thresholds in %.
|
||||
|
||||
=item B<--warning-packets-error-out>
|
||||
|
||||
Thresholds in %.
|
||||
|
||||
=item B<--critical-packets-error-out>
|
||||
|
||||
Thresholds in %.
|
||||
|
||||
=item B<--warning-packets-drop-in>
|
||||
|
||||
Thresholds in %.
|
||||
|
||||
=item B<--critical-packets-drop-in>
|
||||
|
||||
Thresholds in %.
|
||||
|
||||
=item B<--warning-packets-drop-out>
|
||||
|
||||
Thresholds in %.
|
||||
|
||||
=item B<--critical-packets-drop-out>
|
||||
|
||||
Thresholds in %.
|
||||
|
||||
=item B<--warning-total-interfaces>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-total-interfaces>
|
||||
|
||||
Thresholds.
|
||||
Can be: 'traffic-in', 'traffic-out', 'packets-error-in' (%),
|
||||
'packets-error-out' (%), 'packets-drop-in' (%), 'packets-drop-out' (%),
|
||||
'total-interfaces'.
|
||||
|
||||
=back
|
||||
|
||||
|
@ -197,10 +197,13 @@ You can use the following variables: %{state}, %{status}, %{display}
|
||||
Define the conditions to match for the status to be CRITICAL (default: '%{state} eq "enabled" and %{status} eq "red"').
|
||||
You can use the following variables: %{state}, %{status}, %{display}
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
=item B<--warning-current-client-connections>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-current-client-connections>
|
||||
|
||||
Thresholds.
|
||||
Can be: 'current-client-connections'.
|
||||
|
||||
=back
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2025 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
@ -29,7 +29,6 @@ sub new {
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
bless $self, $class;
|
||||
|
||||
$self->{version} = '1.0';
|
||||
$self->{modes} = {
|
||||
'apm' => 'network::f5::bigip::snmp::mode::apm',
|
||||
'connections' => 'network::f5::bigip::snmp::mode::connections',
|
||||
@ -42,6 +41,7 @@ sub new {
|
||||
'node-status' => 'network::f5::bigip::snmp::mode::nodestatus',
|
||||
'pool-status' => 'network::f5::bigip::snmp::mode::poolstatus',
|
||||
'tmm-usage' => 'network::f5::bigip::snmp::mode::tmmusage',
|
||||
'cpu-usage' => 'network::f5::bigip::snmp::mode::cpuusage',
|
||||
'trunks' => 'network::f5::bigip::snmp::mode::trunks',
|
||||
'virtualserver-status' => 'network::f5::bigip::snmp::mode::virtualserverstatus'
|
||||
};
|
||||
|
199
src/network/fortinet/fortigate/restapi/mode/certificates.pm
Normal file
199
src/network/fortinet/fortigate/restapi/mode/certificates.pm
Normal file
@ -0,0 +1,199 @@
|
||||
#
|
||||
# Copyright 2025 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
# service performance.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
package network::fortinet::fortigate::restapi::mode::certificates;
|
||||
|
||||
use base qw(centreon::plugins::templates::counter);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
|
||||
use centreon::plugins::misc;
|
||||
use POSIX;
|
||||
|
||||
my $unitdiv = { s => 1, w => 604800, d => 86400, h => 3600, m => 60 };
|
||||
my $unitdiv_long = { s => 'seconds', w => 'weeks', d => 'days', h => 'hours', m => 'minutes' };
|
||||
|
||||
sub custom_expires_perfdata {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{output}->perfdata_add(
|
||||
nlabel => $self->{nlabel} . '.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{unit} },
|
||||
unit => $self->{instance_mode}->{option_results}->{unit},
|
||||
instances => $self->{result_values}->{name},
|
||||
value => floor($self->{result_values}->{expires_seconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }),
|
||||
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
|
||||
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
|
||||
min => 0
|
||||
);
|
||||
}
|
||||
|
||||
sub custom_expires_threshold {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return $self->{perfdata}->threshold_check(
|
||||
value => floor($self->{result_values}->{expires_seconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }),
|
||||
threshold => [
|
||||
{ label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' },
|
||||
{ label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' },
|
||||
{ label => 'unknown-'. $self->{thlabel}, exit_litteral => 'unknown' }
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
sub custom_status_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return 'status: ' . $self->{result_values}->{status};
|
||||
}
|
||||
|
||||
sub prefix_certificate_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return sprintf(
|
||||
"Certificate '%s' ",
|
||||
$options{instance_value}->{name}
|
||||
);
|
||||
}
|
||||
|
||||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{ name => 'certificates', type => 1, cb_prefix_output => 'prefix_certificate_output', message_multiple => 'All certificates are ok', skipped_code => { -10 => 1 } }
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{certificates} = [
|
||||
{ label => 'status', type => 2, critical_default => '%{status} =~ /expired/i', set => {
|
||||
key_values => [ { name => 'name' }, { name => 'status' } ],
|
||||
closure_custom_output => $self->can('custom_status_output'),
|
||||
closure_custom_perfdata => sub { return 0; },
|
||||
closure_custom_threshold_check => \&catalog_status_threshold_ng
|
||||
}
|
||||
},
|
||||
{ label => 'expires', nlabel => 'certificate.expires', set => {
|
||||
key_values => [ { name => 'expires_seconds' }, { name => 'expires_human' }, { name => 'name' } ],
|
||||
output_template => 'expires in %s',
|
||||
output_use => 'expires_human',
|
||||
closure_custom_perfdata => $self->can('custom_expires_perfdata'),
|
||||
closure_custom_threshold_check => $self->can('custom_expires_threshold')
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
|
||||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
'filter-name:s' => { name => 'filter_name' },
|
||||
'unit:s' => { name => 'unit', default => 's' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
if ($self->{option_results}->{unit} eq '' || !defined($unitdiv->{$self->{option_results}->{unit}})) {
|
||||
$self->{option_results}->{unit} = 's';
|
||||
}
|
||||
}
|
||||
|
||||
sub add_certificate {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return if (!defined($options{entry}->{status}));
|
||||
return if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
|
||||
$options{name} !~ /$self->{option_results}->{filter_name}/);
|
||||
|
||||
$self->{certificates}->{ $options{name} } = {
|
||||
name => $options{name},
|
||||
status => $options{entry}->{status}
|
||||
};
|
||||
if (defined($options{entry}->{valid_to})) {
|
||||
$self->{certificates}->{ $options{name} }->{expires_seconds} = $options{entry}->{valid_to} - time();
|
||||
$self->{certificates}->{ $options{name} }->{expires_seconds} = 0 if ($self->{certificates}->{ $options{name} }->{expires_seconds} < 0);
|
||||
$self->{certificates}->{ $options{name} }->{expires_human} = centreon::plugins::misc::change_seconds(
|
||||
value => $self->{certificates}->{ $options{name} }->{expires_seconds}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $certificates = $options{custom}->request_api(
|
||||
endpoint => '/api/v2/monitor/system/available-certificates'
|
||||
);
|
||||
|
||||
$self->{certificates} = {};
|
||||
|
||||
foreach my $certificate (@{ $certificates->{results} }) {
|
||||
if (defined($certificate->{name}) and defined($certificate->{valid_to}) and defined($certificate->{status})) {
|
||||
$self->add_certificate(name => $certificate->{name}, entry => $certificate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check certificates.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--filter-name>
|
||||
|
||||
Filter certificates by name (can be a regexp).
|
||||
|
||||
=item B<--warning-status>
|
||||
|
||||
Define the conditions to match for the status to be WARNING.
|
||||
You can use the following variables: %{name}, %{status}.
|
||||
|
||||
=item B<--critical-status>
|
||||
|
||||
Define the conditions to match for the status to be CRITICAL (Default: '%{status} =~ /expired/i').
|
||||
You can use the following variables: %{name}, %{status}.
|
||||
|
||||
=item B<--unit>
|
||||
|
||||
Select the unit for expires threshold. May be 's' for seconds, 'm' for minutes,
|
||||
'h' for hours, 'd' for days, 'w' for weeks. Default is seconds.
|
||||
|
||||
=item B<--warning-expires>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=item B<--critical-expires>
|
||||
|
||||
Thresholds.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright 2024 Centreon (http://www.centreon.com/)
|
||||
# Copyright 2025 Centreon (http://www.centreon.com/)
|
||||
#
|
||||
# Centreon is a full-fledged industry-strength solution that meets
|
||||
# the needs in IT infrastructure and application monitoring for
|
||||
@ -33,6 +33,7 @@ sub new {
|
||||
'ha' => 'network::fortinet::fortigate::restapi::mode::ha',
|
||||
'health' => 'network::fortinet::fortigate::restapi::mode::health',
|
||||
'licenses' => 'network::fortinet::fortigate::restapi::mode::licenses',
|
||||
'certificates' => 'network::fortinet::fortigate::restapi::mode::certificates',
|
||||
'system' => 'network::fortinet::fortigate::restapi::mode::system'
|
||||
};
|
||||
|
||||
|
@ -36,17 +36,19 @@ sub new {
|
||||
'cpu' => 'centreon::common::fortinet::fortigate::snmp::mode::cpu',
|
||||
'disk' => 'centreon::common::fortinet::fortigate::snmp::mode::disk',
|
||||
'hardware' => 'centreon::common::fortinet::fortigate::snmp::mode::hardware',
|
||||
'interfaces' => 'centreon::common::fortinet::fortigate::snmp::mode::interfaces',
|
||||
'interfaces' => 'centreon::common::fortinet::fortigate::snmp::mode::interfaces',
|
||||
'ips-stats' => 'centreon::common::fortinet::fortigate::snmp::mode::ipsstats',
|
||||
'link-monitor' => 'centreon::common::fortinet::fortigate::snmp::mode::linkmonitor',
|
||||
'list-interfaces' => 'snmp_standard::mode::listinterfaces',
|
||||
'list-link-monitors' => 'centreon::common::fortinet::fortigate::snmp::mode::listlinkmonitors',
|
||||
'list-virtualdomains' => 'centreon::common::fortinet::fortigate::snmp::mode::listvirtualdomains',
|
||||
'list-switches' => 'centreon::common::fortinet::fortigate::snmp::mode::listswitches',
|
||||
'memory' => 'centreon::common::fortinet::fortigate::snmp::mode::memory',
|
||||
'sessions' => 'centreon::common::fortinet::fortigate::snmp::mode::sessions',
|
||||
'signatures' => 'centreon::common::fortinet::fortigate::snmp::mode::signatures',
|
||||
'uptime' => 'snmp_standard::mode::uptime',
|
||||
'sdwan' => 'centreon::common::fortinet::fortigate::snmp::mode::sdwan',
|
||||
'switch-usage' => 'centreon::common::fortinet::fortigate::snmp::mode::switchusage',
|
||||
'vdom-usage' => 'centreon::common::fortinet::fortigate::snmp::mode::vdomusage',
|
||||
'virus' => 'centreon::common::fortinet::fortigate::snmp::mode::virus',
|
||||
'vpn' => 'centreon::common::fortinet::fortigate::snmp::mode::vpn'
|
||||
|
@ -106,7 +106,7 @@ sub manage_selection {
|
||||
foreach my $oid (keys %$snmp_result) {
|
||||
next if($oid !~ /^$mapping->{uxDSPServiceStatus}->{oid}\.(.*)$/);
|
||||
my $instance = $1;
|
||||
my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance);
|
||||
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance);
|
||||
|
||||
next if ($result->{uxDSPIsPresent} eq '0');
|
||||
|
||||
|
@ -150,7 +150,7 @@ __END__
|
||||
|
||||
Jasmin SMS HTTP-API
|
||||
|
||||
=head1 HTTP API OPTIONS
|
||||
=head1 REST API OPTIONS
|
||||
|
||||
Jasmin SMS HTTP API
|
||||
|
||||
|
@ -79,8 +79,8 @@ Check hardware (batteries, fan modules, fibre channels, flashcards, power suppli
|
||||
|
||||
=item B<--component>
|
||||
|
||||
Which component to check (default: 'all').
|
||||
Can be: 'battery', 'fan', 'fibrechannel', 'flashcard', 'psu'.
|
||||
Which component to check (default: '.*').
|
||||
Can be: C<battery>, C<fan>, C<fibrechannel>, C<flashcard>, C<psu>.
|
||||
|
||||
=item B<--filter>
|
||||
|
||||
@ -89,7 +89,7 @@ You can also exclude items from specific instances: --filter=fan,1
|
||||
|
||||
=item B<--absent-problem>
|
||||
|
||||
Return an error if an entity is not 'notAvailable' (default is skipping) (comma separated list)
|
||||
Return an error if an entity is not C<notAvailable> (default is skipping) (comma separated list).
|
||||
Can be specific or global: --absent-problem=fan,2
|
||||
|
||||
=item B<--no-component>
|
||||
|
51
tests/apps/backup/veeam/vbem/restapi/jobs.robot
Normal file
51
tests/apps/backup/veeam/vbem/restapi/jobs.robot
Normal file
@ -0,0 +1,51 @@
|
||||
*** Settings ***
|
||||
Documentation Check Veeam Backup Enterprise Manager using Rest API,Check jobs.
|
||||
|
||||
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}..${/}resources/import.resource
|
||||
|
||||
Suite Setup Start Mockoon ${MOCKOON_JSON}
|
||||
Suite Teardown Stop Mockoon
|
||||
Test Timeout 120s
|
||||
|
||||
|
||||
*** Variables ***
|
||||
${MOCKOON_JSON} ${CURDIR}${/}restapi.json
|
||||
|
||||
${cmd} ${CENTREON_PLUGINS}
|
||||
... --plugin=apps::backup::veeam::vbem::restapi::plugin
|
||||
... --hostname=${HOSTNAME}
|
||||
... --api-username='username'
|
||||
... --api-password='password'
|
||||
... --proto='http'
|
||||
... --port=${APIPORT}
|
||||
|
||||
*** Test Cases ***
|
||||
Create cache from API
|
||||
[Tags] apps backup veeam vbem restapi jobs cache
|
||||
${output} Run
|
||||
... ${CMD} --mode=cache --proto=http --port=${APIPORT} --hostname=${HOSTNAME}
|
||||
|
||||
Log ${output}
|
||||
Should Contain ${output} OK: Cache files created successfully
|
||||
|
||||
jobs ${tc}
|
||||
[Tags] apps backup veeam vbem restapi jobs
|
||||
|
||||
${command} Catenate
|
||||
... ${cmd}
|
||||
... --mode=jobs
|
||||
... --cache-use
|
||||
... ${extraoptions}
|
||||
|
||||
Ctn Verify Command Output ${command} ${expected_result}
|
||||
|
||||
Examples: tc extraoptions expected_result --
|
||||
... 1 ${EMPTY} OK: All jobs are ok | 'jobs.executions.detected.count'=2;;;0; 'Backup client 2 - Tous les jours#job.executions.failed.percentage'=5.26%;;;0;100 'client 6 - Backup - VM Test et Lab#job.execution.last.seconds'
|
||||
... 2 --critical-execution-status='\\\%{status} eq "Success"' CRITICAL: job 'Backup client 2 - Tous les jours' [type: Backup] execution started: 2025-02-19T11:30:08.103Z status: Success - job 'PROD Job 1' [type: Backup] execution started: 2025-02-19T12:00:11.94Z status: Success | 'jobs.executions.detected.count'=2;;;0;
|
||||
... 3 --warning-execution-status='\\\%{status} eq "Success"' WARNING: job 'Backup client 2 - Tous les jours' [type: Backup] execution started: 2025-02-19T11:30:08.103Z status: Success - job 'PROD Job 1' [type: Backup] execution started: 2025-02-19T12:00:11.94Z status: Success | 'jobs.executions.detected.count'=2;;;0;
|
||||
... 4 --filter-uid='urn:veeam:Job' OK: All jobs are ok | 'jobs.executions.detected.count'=2;;;0; 'Backup client 2 - Tous les jours#job.executions.failed.percentage'=5.26%;;;0;100 'client 6 - Backup - VM Test et Lab#job.execution.last.seconds'
|
||||
... 5 --filter-name='PROD Job 1' CRITICAL: job 'PROD Job 1' [type: Backup] execution started: 2025-02-19T03:51:03.037Z status: Failed | 'jobs.executions.detected.count'=2;;;0; 'PROD Job 1#job.executions.failed.percentage'=50.00%;;;0;100
|
||||
... 6 --filter-type='toto' OK: | 'jobs.executions.detected.count'=0;;;0;
|
||||
... 7 --timeframe='0' OK: All jobs are ok | 'jobs.executions.detected.count'=2;;;0; 'Backup client 2 - Tous les jours#job.executions.failed.percentage'=5.26%;;;0;100 'client 6 - Backup - VM Test et Lab#job.execution.last.seconds'
|
||||
... 8 --unknown-execution-status='\\\%{status} eq "Success"' --filter-name='client 6' --filter-type='Backup' UNKNOWN: job 'client 6 - Backup - Infrastructure g0t0-oob' [type: Backup] execution started: 2025-02-19T11:30:08.103Z status: Success - job 'client 6 - Backup - Infrastructure g0t0-bck' [type: Backup] execution started: 2025-02-19T12:00:11.94Z status: Success | 'jobs.executions.detected.count'=2;;;0;
|
||||
... 9 --warning-job-executions-failed-prct=0 --critical-job-executions-failed-prct=10 CRITICAL: job 'PROD Job 1' [type: Backup] number of failed executions: 60.00 % WARNING: job 'Backup client 2 - Tous les jours' [type: Backup]
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user