Release 20240613 (#5061)

This commit is contained in:
pkippes 2024-06-13 17:31:08 +02:00 committed by GitHub
commit 1af93b29ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
59 changed files with 2888 additions and 590 deletions

View File

@ -24,5 +24,4 @@ runs:
- name: Install, test and remove plugin - name: Install, test and remove plugin
shell: bash shell: bash
run: | run: python3 .github/scripts/test-all-plugins.py ${{ inputs.package-extension }} ${{ inputs.plugin-list }}
python3 .github/scripts/test-all-plugins.py ${{ inputs.package-extension }} ${{ inputs.plugin-list }}

View File

@ -47,6 +47,7 @@ overrides:
perl(Storable), perl(Storable),
perl(POSIX), perl(POSIX),
perl(Encode), perl(Encode),
perl(XML::LibXML),
@RPM_DEPENDENCIES@ @RPM_DEPENDENCIES@
] ]
conflicts: conflicts:
@ -72,6 +73,7 @@ overrides:
libcrypt-argon2-perl, libcrypt-argon2-perl,
libkeepass-reader-perl, libkeepass-reader-perl,
libdatetime-perl, libdatetime-perl,
libxml-libxml-perl,
@DEB_DEPENDENCIES@ @DEB_DEPENDENCIES@
] ]
conflicts: conflicts:

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import glob
import subprocess import subprocess
import sys import sys
import os import os
@ -26,7 +27,7 @@ def test_plugin(plugin_name):
print(f"{plugin_name} folders_list : {folders_list}") print(f"{plugin_name} folders_list : {folders_list}")
if len(folders_list) == 0: if len(folders_list) == 0:
return 0 # no tests present at the moment, but we still have tested the plugin can be installed. return 0 # no tests present at the moment, but we still have tested the plugin can be installed.
robot_results = subprocess.run("robot -v ''CENTREON_PLUGINS:" + get_plugin_full_path(plugin_name) + " " + " ".join(folders_list), robot_results = subprocess.run("robot --exclude notauto -v ''CENTREON_PLUGINS:" + get_plugin_full_path(plugin_name) + " " + " ".join(folders_list),
shell=True, check=False) shell=True, check=False)
return robot_results.returncode return robot_results.returncode
@ -51,13 +52,26 @@ def launch_snmp_sim():
snmpsim_cmd = "snmpsim-command-responder --logging-method=null --agent-udpv4-endpoint=127.0.0.1:2024 --process-user=snmp --process-group=snmp --data-dir='./tests/robot' &" snmpsim_cmd = "snmpsim-command-responder --logging-method=null --agent-udpv4-endpoint=127.0.0.1:2024 --process-user=snmp --process-group=snmp --data-dir='./tests/robot' &"
try_command(cmd=snmpsim_cmd, error="can't launch snmp sim daemon.") try_command(cmd=snmpsim_cmd, error="can't launch snmp sim daemon.")
def refresh_packet_manager(archi):
with open('/var/log/robot-plugins-installation-tests.log', "a") as outfile:
if archi == "deb":
outfile.write("apt-get update\n")
output_status = (subprocess.run(
"apt-get update",
shell=True, check=False, stderr=subprocess.STDOUT, stdout=outfile)).returncode
elif archi == "rpm":
return 0
else:
print(f"Unknown architecture, expected deb or rpm, got {archi}. Exiting.")
exit(1)
return output_status
def install_plugin(plugin, archi): def install_plugin(plugin, archi):
with open('/var/log/robot-plugins-installation-tests.log', "a") as outfile: with open('/var/log/robot-plugins-installation-tests.log', "a") as outfile:
if archi == "deb": if archi == "deb":
outfile.write("apt install -o 'Binary::apt::APT::Keep-Downloaded-Packages=1;' -y ./" + plugin.lower() + "*.deb\n") outfile.write("apt-get install -o 'Binary::apt::APT::Keep-Downloaded-Packages=1;' -y ./" + plugin.lower() + "*.deb\n")
output_status = (subprocess.run( output_status = (subprocess.run(
"apt install -o 'Binary::apt::APT::Keep-Downloaded-Packages=1;' -y ./" + plugin.lower() + "*.deb", "apt-get install -o 'Binary::apt::APT::Keep-Downloaded-Packages=1;' -y ./" + plugin.lower() + "*.deb",
shell=True, check=False, stderr=subprocess.STDOUT, stdout=outfile)).returncode shell=True, check=False, stderr=subprocess.STDOUT, stdout=outfile)).returncode
elif archi == "rpm": elif archi == "rpm":
outfile.write("dnf install -y ./" + plugin + "*.rpm\n") outfile.write("dnf install -y ./" + plugin + "*.rpm\n")
@ -72,9 +86,9 @@ def install_plugin(plugin, archi):
def remove_plugin(plugin, archi): def remove_plugin(plugin, archi):
with open('/var/log/robot-plugins-installation-tests.log', "a") as outfile: with open('/var/log/robot-plugins-installation-tests.log', "a") as outfile:
if archi == "deb": if archi == "deb":
outfile.write("apt -o 'Binary::apt::APT::Keep-Downloaded-Packages=1;' autoremove -y " + plugin.lower() + "\n") outfile.write("apt-get -o 'Binary::apt::APT::Keep-Downloaded-Packages=1;' autoremove -y " + plugin.lower() + "\n")
output_status = (subprocess.run( output_status = (subprocess.run(
"apt -o 'Binary::apt::APT::Keep-Downloaded-Packages=1;' autoremove -y " + plugin.lower(), "apt-get -o 'Binary::apt::APT::Keep-Downloaded-Packages=1;' autoremove -y " + plugin.lower(),
shell=True, check=False, stderr=subprocess.STDOUT, stdout=outfile)).returncode shell=True, check=False, stderr=subprocess.STDOUT, stdout=outfile)).returncode
# -o 'Binary::apt::APT::Keep-Downloaded-Packages=1;' is an option to force apt to keep the package in # -o 'Binary::apt::APT::Keep-Downloaded-Packages=1;' is an option to force apt to keep the package in
# /var/cache/apt/archives, so it do not re download them for every installation. # /var/cache/apt/archives, so it do not re download them for every installation.
@ -87,6 +101,13 @@ def remove_plugin(plugin, archi):
else: else:
print(f"Unknown architecture, expected deb or rpm, got {archi}. Exiting.") print(f"Unknown architecture, expected deb or rpm, got {archi}. Exiting.")
exit(1) exit(1)
# Remove cache files
tmp_files = glob.glob('/tmp/cache/*')
for file in tmp_files:
try:
os.remove(file)
except Exception as e:
print(f"Erreur while removing file {file} : {str(e)}")
return output_status return output_status
@ -101,13 +122,25 @@ if __name__ == '__main__':
archi = sys.argv.pop(1) # expected either deb or rpm. archi = sys.argv.pop(1) # expected either deb or rpm.
script_name = sys.argv.pop(0) script_name = sys.argv.pop(0)
# Create a directory for cache files
os.mkdir("/tmp/cache")
error_install = 0 error_install = 0
error_tests = 0 error_tests = 0
error_purge = 0 error_purge = 0
nb_plugins = 0 nb_plugins = 0
list_plugin_error = [] list_plugin_error = []
# call apt update (or maybe dnf clean all if needed)
refresh_packet_manager(archi)
for plugin in sys.argv: for plugin in sys.argv:
print("plugin : ", plugin) print("plugin : ", plugin)
folders_list = get_tests_folders(plugin)
if len(folders_list) == 0:
print(f"we don't test {plugin} as it don't have any robots tests.")
continue
nb_plugins += 1 nb_plugins += 1
tmp = install_plugin(plugin, archi) tmp = install_plugin(plugin, archi)
if tmp > 0: if tmp > 0:

View File

@ -51,22 +51,22 @@ jobs:
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Login to Registry - name: Login to Registry
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with: with:
registry: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }} registry: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}
username: ${{ secrets.DOCKER_REGISTRY_ID }} username: ${{ secrets.DOCKER_REGISTRY_ID }}
password: ${{ secrets.DOCKER_REGISTRY_PASSWD }} password: ${{ secrets.DOCKER_REGISTRY_PASSWD }}
- name: Login to proxy registry - name: Login to proxy registry
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with: with:
registry: ${{ vars.DOCKER_PROXY_REGISTRY_URL }} registry: ${{ vars.DOCKER_PROXY_REGISTRY_URL }}
username: ${{ secrets.DOCKER_REGISTRY_ID }} username: ${{ secrets.DOCKER_REGISTRY_ID }}
password: ${{ secrets.DOCKER_REGISTRY_PASSWD }} password: ${{ secrets.DOCKER_REGISTRY_PASSWD }}
- uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 - uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0
- uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0 - uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
with: with:
file: .github/docker/packaging/Dockerfile.${{ matrix.dockerfile }} file: .github/docker/packaging/Dockerfile.${{ matrix.dockerfile }}
context: . context: .

View File

@ -61,7 +61,7 @@ jobs:
username: ${{ secrets.DOCKER_REGISTRY_ID }} username: ${{ secrets.DOCKER_REGISTRY_ID }}
password: ${{ secrets.DOCKER_REGISTRY_PASSWD }} password: ${{ secrets.DOCKER_REGISTRY_PASSWD }}
- uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 - uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0
- uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0 - uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0
with: with:

View File

@ -68,15 +68,18 @@ jobs:
"JSON::WebToken", "JSON::WebToken",
"LV", "LV",
"MIME::Types", "MIME::Types",
"Mojo::IOLoop::Signal",
"MongoDB", "MongoDB",
"Net::DHCP", "Net::DHCP",
"Net::FTPSSL", "Net::FTPSSL",
"Net::HTTPTunnel", "Net::HTTPTunnel",
"Net::MQTT::Simple",
"Net::NTP", "Net::NTP",
"Net::SMTPS", "Net::SMTPS",
"Net::SMTP_auth", "Net::SMTP_auth",
"Net::Subnet", "Net::Subnet",
"Net::TFTP", "Net::TFTP",
"Paws",
"PBKDF2::Tiny", "PBKDF2::Tiny",
"Schedule::Cron", "Schedule::Cron",
"Statistics::Descriptive", "Statistics::Descriptive",
@ -103,7 +106,6 @@ jobs:
- rpm_dependencies: "" - rpm_dependencies: ""
- rpm_provides: "" - rpm_provides: ""
- version: "" - version: ""
- use_dh_make_perl: "true"
- spec_file: "" - spec_file: ""
- distrib: el8 - distrib: el8
package_extension: rpm package_extension: rpm
@ -113,19 +115,15 @@ jobs:
image: packaging-plugins-alma9 image: packaging-plugins-alma9
- name: "BSON" - name: "BSON"
rpm_provides: "perl(BSON::Bytes) perl(BSON::Code) perl(BSON::DBRef) perl(BSON::OID) perl(BSON::Raw) perl(BSON::Regex) perl(BSON::Time) perl(BSON::Timestamp) perl(BSON::Types) perl(BSON)" rpm_provides: "perl(BSON::Bytes) perl(BSON::Code) perl(BSON::DBRef) perl(BSON::OID) perl(BSON::Raw) perl(BSON::Regex) perl(BSON::Time) perl(BSON::Timestamp) perl(BSON::Types) perl(BSON)"
- name: "BSON::XS"
- name: "Convert::Binary::C"
- name: "DateTime::Format::Duration::ISO8601" - name: "DateTime::Format::Duration::ISO8601"
rpm_provides: "perl(DateTime-Format-Duration-ISO8601)" rpm_provides: "perl(DateTime-Format-Duration-ISO8601)"
- name: "DBD::Sybase"
- name: "Device::Modbus::RTU::Client" - name: "Device::Modbus::RTU::Client"
version: "0.022" version: "0.022"
- name: "Device::Modbus::TCP::Client" - name: "Device::Modbus::TCP::Client"
version: "0.026" version: "0.026"
- name: "Exporter::Shiny" - name: "Exporter::Shiny"
build_distribs: el8 build_distribs: el8
- name: "EV" rpm_provides: "perl(Exporter::Shiny) perl(Exporter::Tiny)"
- name: "FFI::CheckLib"
- name: "FFI::Platypus" - name: "FFI::Platypus"
rpm_provides: "perl(FFI::Platypus::Buffer) perl(FFI::Platypus::Memory)" rpm_provides: "perl(FFI::Platypus::Buffer) perl(FFI::Platypus::Memory)"
- name: "Net::DHCP" - name: "Net::DHCP"
@ -133,14 +131,12 @@ jobs:
- name: "Statistics::Regression" - name: "Statistics::Regression"
version: "0.53" version: "0.53"
- name: "UUID" - name: "UUID"
use_dh_make_perl: "false"
version: "0.31" version: "0.31"
- name: "ZMQ::Constants" - name: "ZMQ::Constants"
build_distribs: "el9" build_distribs: "el9"
- name: "ZMQ::FFI" - name: "ZMQ::FFI"
rpm_dependencies: "zeromq" rpm_dependencies: "zeromq"
- name: "ZMQ::LibZMQ4" - name: "ZMQ::LibZMQ4"
use_dh_make_perl: "false"
version: "0.01" version: "0.01"
rpm_dependencies: "zeromq" rpm_dependencies: "zeromq"
@ -160,7 +156,7 @@ jobs:
yum install -y yum-utils epel-release git yum install -y yum-utils epel-release git
yum config-manager --set-enabled crb || true # alma 9 yum config-manager --set-enabled crb || true # alma 9
yum config-manager --set-enabled powertools || true # alma 8 yum config-manager --set-enabled powertools || true # alma 8
yum install -y cpanminus rpm-build libcurl-devel libssh-devel expat-devel gcc libuuid-devel zeromq-devel libxml2-devel libffi-devel perl-DBI perl-Net-Pcap freetds freetds-devel yum install -y cpanminus rpm-build libcurl-devel libssh-devel expat-devel gcc libuuid-devel zeromq-devel libxml2-devel libffi-devel perl-DBI perl-Net-Pcap freetds freetds-devel perl-Module-Build-Tiny
dnf module reset -y ruby dnf module reset -y ruby
dnf module enable -y ruby:3.1 dnf module enable -y ruby:3.1
@ -226,15 +222,92 @@ jobs:
path: ./*.${{ matrix.package_extension }} path: ./*.${{ matrix.package_extension }}
retention-days: 1 retention-days: 1
merge-package-rpm-artifacts:
needs: [package-rpm]
runs-on: ubuntu-22.04
strategy:
matrix:
distrib: [el8, el9]
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Merging Artifacts
uses: ./.github/actions/merge-artifacts
with:
target_name: packages-rpm-${{ matrix.distrib }}
source_paths: packages-rpm-${{ matrix.distrib }}/*.rpm
source_name_pattern: packages-rpm-${{ matrix.distrib }}-
github_token: ${{ secrets.GITHUB_TOKEN }}
sign-rpm:
needs: [merge-package-rpm-artifacts]
runs-on: ubuntu-22.04
strategy:
matrix:
distrib: [el8, el9]
name: sign rpm ${{ matrix.distrib }}
container:
image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/rpm-signing:ubuntu
options: -t
credentials:
username: ${{ secrets.DOCKER_REGISTRY_ID }}
password: ${{ secrets.DOCKER_REGISTRY_PASSWD }}
steps:
- run: apt-get install -y zstd
shell: bash
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
name: packages-rpm-${{ matrix.distrib }}
path: ./
- run: echo "HOME=/root" >> $GITHUB_ENV
shell: bash
- run: rpmsign --addsign ./*.rpm
shell: bash
- uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with:
path: ./*.rpm
key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
deliver-rpm:
needs: [get-environment, sign-rpm]
if: ${{ contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) }}
runs-on: [self-hosted, common]
strategy:
matrix:
distrib: [el8, el9]
steps:
- name: Checkout sources
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Delivery
uses: ./.github/actions/rpm-delivery
with:
module_name: perl-cpan-libraries
distrib: ${{ matrix.distrib }}
artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
cache_key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
stability: ${{ needs.get-environment.outputs.stability }}
package-deb: package-deb:
needs: [get-environment] needs: [get-environment]
if: ${{ needs.get-environment.outputs.stability != 'stable' }} if: ${{ needs.get-environment.outputs.stability != 'stable' }}
runs-on: ubuntu-22.04 runs-on: ${{ matrix.runner_name }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
distrib: [bullseye, bookworm, jammy] image: [packaging-plugins-bullseye, packaging-plugins-bookworm, packaging-plugins-jammy, packaging-plugins-bullseye-arm64]
name: name:
[ [
"Authen::SCRAM::Client", "Authen::SCRAM::Client",
@ -247,15 +320,20 @@ jobs:
"Hash::Ordered", "Hash::Ordered",
"HTTP::ProxyPAC", "HTTP::ProxyPAC",
"JMX::Jmx4Perl", "JMX::Jmx4Perl",
"Mojo::IOLoop::Signal",
"Net::FTPSSL", "Net::FTPSSL",
"Net::HTTPTunnel", "Net::HTTPTunnel",
"Net::MQTT::Simple",
"Net::SMTP_auth", "Net::SMTP_auth",
"Paws",
"Statistics::Regression", "Statistics::Regression",
"WWW::Selenium", "WWW::Selenium",
"ZMQ::Constants", "ZMQ::Constants",
"ZMQ::LibZMQ4" "ZMQ::LibZMQ4"
] ]
include: include:
- runner_name: ubuntu-22.04
- arch: amd64
- build_distribs: "bullseye,bookworm,jammy" - build_distribs: "bullseye,bookworm,jammy"
- deb_dependencies: "" - deb_dependencies: ""
- rpm_provides: "" - rpm_provides: ""
@ -271,6 +349,13 @@ jobs:
- distrib: jammy - distrib: jammy
package_extension: deb package_extension: deb
image: packaging-plugins-jammy image: packaging-plugins-jammy
- distrib: bullseye
package_extension: deb
image: packaging-plugins-bullseye-arm64
arch: arm64
runner_name: ["self-hosted", "collect-arm64"]
- name: "Paws"
use_dh_make_perl: "false"
- name: "Statistics::Regression" - name: "Statistics::Regression"
build_distribs: "bullseye" build_distribs: "bullseye"
version: "0.53" version: "0.53"
@ -278,7 +363,7 @@ jobs:
use_dh_make_perl: "false" use_dh_make_perl: "false"
version: "0.01" version: "0.01"
deb_dependencies: "libzmq5" deb_dependencies: "libzmq5"
name: package ${{ matrix.distrib }} ${{ matrix.name }} name: package ${{ matrix.distrib }} ${{ matrix.arch }} ${{ matrix.name }}
container: container:
image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/${{ matrix.image }}:latest image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/${{ matrix.image }}:latest
credentials: credentials:
@ -330,12 +415,13 @@ jobs:
cpanm Module::Install cpanm Module::Install
gem install fpm gem install fpm
fpm -s cpan -t ${{ matrix.package_extension }} --deb-dist ${{ matrix.distrib }} --iteration ${{ matrix.distrib }} --verbose --cpan-verbose --no-cpan-test -n $PACKAGE_NAME$PACKAGE_DEPENDENCIES -v ${{ steps.package-version.outputs.package_version }} ${{ matrix.name }} fpm -a native -s cpan -t ${{ matrix.package_extension }} --deb-dist ${{ matrix.distrib }} --iteration ${{ matrix.distrib }} --verbose --cpan-verbose --no-cpan-test -n $PACKAGE_NAME$PACKAGE_DEPENDENCIES -v ${{ steps.package-version.outputs.package_version }} ${{ matrix.name }}
shell: bash shell: bash
- if: ${{ contains(matrix.build_distribs, matrix.distrib) && matrix.use_dh_make_perl == 'true' }} - if: ${{ contains(matrix.build_distribs, matrix.distrib) && matrix.use_dh_make_perl == 'true' }}
run: | run: |
apt-get install -y libcurl4-openssl-dev dh-make-perl libssh-dev uuid-dev libczmq-dev libmodule-install-perl apt-get install -y libcurl4-openssl-dev dh-make-perl libssh-dev uuid-dev libczmq-dev libmodule-install-perl libmodule-build-tiny-perl
# module-build-tiny is required for Mojo::IOLoop::Signal build.
DEB_BUILD_OPTIONS="nocheck nodocs notest" dh-make-perl make --dist ${{ matrix.distrib }} --build --version ${{ steps.package-version.outputs.package_version }}-${{ matrix.distrib }} --cpan ${{ matrix.name }} DEB_BUILD_OPTIONS="nocheck nodocs notest" dh-make-perl make --dist ${{ matrix.distrib }} --build --version ${{ steps.package-version.outputs.package_version }}-${{ matrix.distrib }} --cpan ${{ matrix.name }}
shell: bash shell: bash
@ -353,27 +439,10 @@ jobs:
- if: ${{ contains(matrix.build_distribs, matrix.distrib) }} - if: ${{ contains(matrix.build_distribs, matrix.distrib) }}
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
with: with:
name: packages-${{ matrix.package_extension }}-${{ matrix.distrib }}-${{ steps.package-name.outputs.name_with_dash}} name: packages-${{ matrix.package_extension }}-${{ matrix.distrib }}-${{ matrix.arch }}-${{ steps.package-name.outputs.name_with_dash}}
path: ./*.${{ matrix.package_extension }} path: ./*.${{ matrix.package_extension }}
retention-days: 1 retention-days: 1
merge-package-rpm-artifacts:
needs: [package-rpm]
runs-on: ubuntu-22.04
strategy:
matrix:
distrib: [el8, el9]
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Merging Artifacts
uses: ./.github/actions/merge-artifacts
with:
target_name: packages-rpm-${{ matrix.distrib }}
source_paths: packages-rpm-${{ matrix.distrib }}/*.rpm
source_name_pattern: packages-rpm-${{ matrix.distrib }}-
github_token: ${{ secrets.GITHUB_TOKEN }}
merge-package-deb-artifacts: merge-package-deb-artifacts:
needs: [package-deb] needs: [package-deb]
@ -393,43 +462,6 @@ jobs:
source_name_pattern: packages-deb-${{ matrix.distrib }}- source_name_pattern: packages-deb-${{ matrix.distrib }}-
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
sign-rpm:
needs: [merge-package-rpm-artifacts]
runs-on: ubuntu-22.04
strategy:
matrix:
distrib: [el8, el9]
name: sign rpm ${{ matrix.distrib }}
container:
image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/rpm-signing:ubuntu
options: -t
credentials:
username: ${{ secrets.DOCKER_REGISTRY_ID }}
password: ${{ secrets.DOCKER_REGISTRY_PASSWD }}
steps:
- run: apt-get install -y zstd
shell: bash
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/download-artifact@87c55149d96e628cc2ef7e6fc2aab372015aec85 # v4.1.3
with:
name: packages-rpm-${{ matrix.distrib }}
path: ./
- run: echo "HOME=/root" >> $GITHUB_ENV
shell: bash
- run: rpmsign --addsign ./*.rpm
shell: bash
- uses: actions/cache/save@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
with:
path: ./*.rpm
key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
download-and-cache-deb: download-and-cache-deb:
needs: [merge-package-deb-artifacts] needs: [merge-package-deb-artifacts]
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
@ -437,38 +469,16 @@ jobs:
matrix: matrix:
distrib: [bullseye, bookworm, jammy] distrib: [bullseye, bookworm, jammy]
steps: steps:
- uses: actions/download-artifact@87c55149d96e628cc2ef7e6fc2aab372015aec85 # v4.1.3 - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with: with:
name: packages-deb-${{ matrix.distrib }} name: packages-deb-${{ matrix.distrib }}
path: ./ path: ./
- uses: actions/cache/save@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 - uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with: with:
path: ./*.deb path: ./*.deb
key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }} key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }}
deliver-rpm:
needs: [get-environment, sign-rpm]
if: ${{ contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) }}
runs-on: [self-hosted, common]
strategy:
matrix:
distrib: [el8, el9]
steps:
- name: Checkout sources
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Delivery
uses: ./.github/actions/rpm-delivery
with:
module_name: perl-cpan-libraries
distrib: ${{ matrix.distrib }}
artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
cache_key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
stability: ${{ needs.get-environment.outputs.stability }}
deliver-deb: deliver-deb:
needs: [get-environment, download-and-cache-deb] needs: [get-environment, download-and-cache-deb]
if: ${{ contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) }} if: ${{ contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) }}

View File

@ -61,7 +61,7 @@ jobs:
cp -r ~/rpmbuild/RPMS/x86_64/*.rpm . cp -r ~/rpmbuild/RPMS/x86_64/*.rpm .
shell: bash shell: bash
- uses: actions/cache/save@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 - uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with: with:
path: ./*.rpm path: ./*.rpm
key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
@ -92,7 +92,7 @@ jobs:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/cache/restore@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 - uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with: with:
path: ./*.rpm path: ./*.rpm
key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
@ -103,7 +103,7 @@ jobs:
- run: rpmsign --addsign ./*.rpm - run: rpmsign --addsign ./*.rpm
shell: bash shell: bash
- uses: actions/cache/save@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 - uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with: with:
path: ./*.rpm path: ./*.rpm
key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
@ -142,7 +142,7 @@ jobs:
DEB_BUILD_OPTIONS="nocheck nodocs notest noautodbgsym" dh-make-perl make --dist ${{ matrix.distrib }} --verbose --build --version 4.0-${{ matrix.distrib }} perl-filesys-smbclient/ DEB_BUILD_OPTIONS="nocheck nodocs notest noautodbgsym" dh-make-perl make --dist ${{ matrix.distrib }} --verbose --build --version 4.0-${{ matrix.distrib }} perl-filesys-smbclient/
shell: bash shell: bash
- uses: actions/cache/save@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 - uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with: with:
path: ./*.deb path: ./*.deb
key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }} key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }}

View File

@ -9,6 +9,7 @@ on:
pull_request: pull_request:
paths: paths:
- "dependencies/perl-json-path/**" - "dependencies/perl-json-path/**"
- ".github/workflows/perl-json-path.yml"
push: push:
branches: branches:
- develop - develop
@ -17,6 +18,7 @@ on:
- "[2-9][0-9].[0-9][0-9].x" - "[2-9][0-9].[0-9][0-9].x"
paths: paths:
- "dependencies/perl-json-path/**" - "dependencies/perl-json-path/**"
- ".github/workflows/perl-json-path.yml"
jobs: jobs:
get-environment: get-environment:

View File

@ -41,7 +41,7 @@ jobs:
shell: bash shell: bash
- name: Cache vsphere cli sources - name: Cache vsphere cli sources
uses: actions/cache/save@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with: with:
path: vmware-vsphere-cli-distrib path: vmware-vsphere-cli-distrib
key: ${{ github.sha }}-${{ github.run_id }}-sources-perl-vmware-vsphere key: ${{ github.sha }}-${{ github.run_id }}-sources-perl-vmware-vsphere
@ -98,7 +98,7 @@ jobs:
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Import source files - name: Import source files
uses: actions/cache/restore@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with: with:
path: vmware-vsphere-cli-distrib path: vmware-vsphere-cli-distrib
key: ${{ github.sha }}-${{ github.run_id }}-sources-perl-vmware-vsphere key: ${{ github.sha }}-${{ github.run_id }}-sources-perl-vmware-vsphere

View File

@ -55,7 +55,7 @@ jobs:
cp -r ~/rpmbuild/RPMS/x86_64/*.rpm . cp -r ~/rpmbuild/RPMS/x86_64/*.rpm .
shell: bash shell: bash
- uses: actions/cache/save@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 - uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with: with:
path: ./*.rpm path: ./*.rpm
key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
@ -86,7 +86,7 @@ jobs:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/cache/restore@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 - uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with: with:
path: ./*.rpm path: ./*.rpm
key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
@ -97,7 +97,7 @@ jobs:
- run: rpmsign --addsign ./*.rpm - run: rpmsign --addsign ./*.rpm
shell: bash shell: bash
- uses: actions/cache/save@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 - uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with: with:
path: ./*.rpm path: ./*.rpm
key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}

View File

@ -30,7 +30,7 @@ jobs:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/cache/restore@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 - uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with: with:
path: ./build/ path: ./build/
key: fatpacked-plugins-${{ github.sha }}-${{ github.run_id }} key: fatpacked-plugins-${{ github.sha }}-${{ github.run_id }}

View File

@ -33,11 +33,11 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0
with: with:
python-version: '3.9' python-version: '3.9'
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: filter id: filter
with: with:
base: ${{ github.ref }} base: ${{ github.ref }}
@ -104,7 +104,7 @@ jobs:
COMMIT=$(git log -1 HEAD --pretty=format:%h) 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)" perl .github/scripts/plugins-source.container.pl "${{ needs.get-plugins.outputs.plugins }}" "${{ needs.get-environment.outputs.version }} ($COMMIT)"
- uses: actions/cache/save@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 - uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with: with:
path: ./build/ path: ./build/
key: fatpacked-plugins-${{ github.sha }}-${{ github.run_id }} key: fatpacked-plugins-${{ github.sha }}-${{ github.run_id }}
@ -163,7 +163,7 @@ jobs:
fail-on-cache-miss: true fail-on-cache-miss: true
- if: ${{ matrix.distrib != 'el7' }} - if: ${{ matrix.distrib != 'el7' }}
uses: actions/cache/restore@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with: with:
path: ./build/ path: ./build/
key: fatpacked-plugins-${{ github.sha }}-${{ github.run_id }} key: fatpacked-plugins-${{ github.sha }}-${{ github.run_id }}

View File

@ -20,7 +20,7 @@ jobs:
steps: steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: filter id: filter
with: with:
base: ${{ github.ref }} base: ${{ github.ref }}

View File

@ -0,0 +1,5 @@
{
"dependencies": [
"libnet-mqtt-simple-perl"
]
}

View File

@ -0,0 +1,10 @@
{
"pkg_name": "centreon-plugin-Applications-Eclipse-Mosquitto-Mqtt",
"pkg_summary": "Centreon Plugin to monitor Eclipse Mosquitto throught MQTT",
"plugin_name": "centreon_eclipse_mosquitto_mqtt.pl",
"files": [
"centreon/plugins/script_mqtt.pm",
"centreon/plugins/mqtt.pm",
"apps/eclipse/mosquitto/mqtt/"
]
}

View File

@ -0,0 +1,5 @@
{
"dependencies": [
"perl(Net::MQTT::Simple)"
]
}

View File

@ -1,7 +1,9 @@
{ {
"dependencies": [ "dependencies": [
"libjson-maybexs-perl",
"libjson-perl", "libjson-perl",
"libxml-xpath-perl", "libxml-xpath-perl",
"libxml-libxml-perl",
"libxml-libxml-simple-perl" "libxml-libxml-simple-perl"
] ]
} }

View File

@ -1,20 +1,20 @@
{ {
"pkg_name": "centreon-plugin-Applications-TrendMicro-Iwsva", "pkg_name": "centreon-plugin-Applications-TrendMicro-Iwsva",
"pkg_summary": "Centreon Plugin", "pkg_summary": "Centreon Plugin to monitor TrendMicro Iwsva throught SNMP",
"plugin_name": "centreon_trendmicro_iwsva.pl", "plugin_name": "centreon_trendmicro_iwsva.pl",
"files": [ "files": [
"centreon/plugins/script_snmp.pm", "centreon/plugins/script_snmp.pm",
"centreon/plugins/snmp.pm", "centreon/plugins/snmp.pm",
"snmp_standard/mode/cpu.pm", "snmp_standard/mode/cpu.pm",
"snmp_standard/mode/interfaces.pm", "snmp_standard/mode/interfaces.pm",
"snmp_standard/mode/loadaverage.pm",
"snmp_standard/mode/listinterfaces.pm", "snmp_standard/mode/listinterfaces.pm",
"snmp_standard/mode/resources/",
"snmp_standard/mode/liststorages.pm", "snmp_standard/mode/liststorages.pm",
"snmp_standard/mode/loadaverage.pm",
"snmp_standard/mode/memory.pm", "snmp_standard/mode/memory.pm",
"snmp_standard/mode/resources/",
"snmp_standard/mode/storage.pm", "snmp_standard/mode/storage.pm",
"snmp_standard/mode/swap.pm", "snmp_standard/mode/swap.pm",
"snmp_standard/mode/tcpcon.pm", "snmp_standard/mode/tcpcon.pm",
"os/linux/snmp/" "apps/trendmicro/iwsva/snmp/"
] ]
} }

View File

@ -1,4 +1,5 @@
{ {
"dependencies": [ "dependencies": [
"perl(DateTime)"
] ]
} }

View File

@ -0,0 +1,90 @@
#
# 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 apps::eclipse::mosquitto::mqtt::mode::clients;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0 }
];
$self->{maps_counters}->{global} = [];
for my $label (('connected', 'maximum', 'active', 'inactive')) {
push @{$self->{maps_counters}->{global}},
{ label => 'clients-' . $label,
nlabel => 'clients.' . $label . '.count',
set => {
key_values => [{ name => $label }],
output_template => ucfirst($label) . ' clients: %d',
perfdatas => [
{ label => $label . '_clients', template => '%d',
min => 0 }
]
}
};
}
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
return $self;
}
sub manage_selection {
my ($self, %options) = @_;
my %results = $options{mqtt}->queries(
base_topic => '$SYS/broker/clients/',
topics => ['connected', 'maximum', 'active', 'inactive']
);
for my $topic (keys %results) {
$self->{global}->{$topic} = $results{$topic};
}
}
1;
__END__
=head1 MODE
Check clients statistics.
=over 8
=item B<--warning-*> B<--critical-*>
Thresholds.
Can be: 'clients-connected', 'clients-maximum', 'clients-active', 'clients-inactive'.
=back
=cut

View File

@ -0,0 +1,89 @@
#
# 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 apps::eclipse::mosquitto::mqtt::mode::messages;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0 }
];
$self->{maps_counters}->{global} = [];
for my $label (('stored', 'received', 'sent')) {
push @{$self->{maps_counters}->{global}},
{ label => 'messages-' . $label,
nlabel => 'messages.' . $label . '.count',
set => {
key_values => [{ name => $label }],
output_template => ucfirst($label) . ' messages: %d',
perfdatas => [
{ label => $label . '_messages', template => '%d',
min => 0 }
]
}
};
}
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
return $self;
}
sub manage_selection {
my ($self, %options) = @_;
my %results = $options{mqtt}->queries(
base_topic => '$SYS/broker/messages/',
topics => ['stored', 'received', 'sent']
);
for my $topic (keys %results) {
$self->{global}->{$topic} = $results{$topic};
}
}
1;
__END__
=head1 MODE
Check messages statistics.
=over 8
=item B<--warning-*> B<--critical-*>
Thresholds.
Can be: 'messages-stored', 'messages-received', 'messages-sent'.
=back
=cut

View File

@ -0,0 +1,205 @@
#
# 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 apps::eclipse::mosquitto::mqtt::mode::numericvalue;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::misc;
use Time::HiRes qw(time);
use POSIX qw(floor);
sub new {
my ($class, %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' },
'extracted-pattern:s' => { name => 'extracted_pattern' },
'format:s' => { name => 'format' },
'format-custom:s' => { name => 'format_custom' },
'perfdata-unit:s' => { name => 'perfdata_unit' },
'perfdata-name:s' => { name => 'perfdata_name', default => 'value' },
'perfdata-min:s' => { name => 'perfdata_min' },
'perfdata-max:s' => { name => 'perfdata_max' },
});
return $self;
}
sub custom_generic_output {
my ($self, %options) = @_;
my $format = $self->{instance_mode}{option_results}->{perfdata_name} . ' is: %s';
if (defined($self->{instance_mode}{option_results}->{format})) {
$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);
}
sub custom_generic_perfdata {
my ($self, %options) = @_;
$self->{output}->perfdata_add(
label => $options{option_results}->{perfdata_name},
unit => $options{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}
);
}
sub custom_generic_threshold {
my ($self, %options) = @_;
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' }
]
);
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0 }
];
$self->{maps_counters}->{global} = [
{ label => 'generic',
set => {
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')
}
}
];
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
if (centreon::plugins::misc::is_empty($options{option_results}->{topic})) {
$self->{output}->add_option_msg(short_msg => 'Missing parameter --topic.');
$self->{output}->option_exit();
}
}
sub manage_selection {
my ($self, %options) = @_;
my $value = $options{mqtt}->query(
topic => $self->{option_results}->{topic}
);
if (!centreon::plugins::misc::is_empty($self->{option_results}->{extracted_pattern})) {
if ($value =~ /$self->{option_results}->{extracted_pattern}/ && defined($1)) {
$value = $1;
}
}
if ($value !~ /^-?\d+(?:\.\d+)?$/) {
$self->{output}->output_add(
severity => 'UNKNOWN',
short_msg => 'topic value is not numeric (' . $value . ')'
);
return;
}
if (!defined($value)) {
$self->{output}->add_option_msg(short_msg => "Cannot find information");
$self->{output}->option_exit();
}
$self->{global} = { numericvalue => $value };
}
1;
__END__
=head1 MODE
Check an Eclipse Mosquitto MQTT topic numeric value.
=over 8
=item B<--topic>
Topic value to check.
=item B<--warning>
Warning threshold.
=item B<--critical>
Critical threshold.
=item B<--extracted-pattern>
Define a pattern to extract a number from the returned string.
=item B<--format>
Output format (default: 'current value is %s')
=item B<--format-custom>
Apply a custom change on the value
(example to multiply the value: --format-custom='* 8').
=item B<--perfdata-unit>
Perfdata unit in perfdata output (default: '')
=item B<--perfdata-name>
Perfdata name in perfdata output (default: 'value')
=item B<--perfdata-min>
Minimum value to add in perfdata output (default: '')
=item B<--perfdata-max>
Maximum value to add in perfdata output (default: '')
=back
=cut

View File

@ -0,0 +1,180 @@
#
# 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 apps::eclipse::mosquitto::mqtt::mode::stringvalue;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::misc;
use Time::HiRes qw(time);
use POSIX qw(floor);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$options{options}->add_options(arguments => {
'topic:s' => { name => 'topic' },
'format-custom' => { name => 'format_custom' },
'warning-regexp:s' => { name => 'warning_regexp' },
'critical-regexp:s' => { name => 'critical_regexp' },
'unknown-regexp:s' => { name => 'unknown_regexp' },
'regexp-insensitive' => { name => 'use_iregexp' },
'format-ok:s' => { name => 'format_ok', default => 'value: %{value}' },
'format-warning:s' => { name => 'format_warning', default => 'value: %{value}' },
'format-critical:s' => { name => 'format_critical', default => 'value: %{value}' },
'format-unknown:s' => { name => 'format_unknown', default => 'value: %{value}' },
});
return $self;
}
sub custom_stringvalue_output {
my ($self, %options) = @_;
my $value = $self->{result_values}->{stringvalue};
if (!centreon::plugins::misc::is_empty($self->{instance_mode}->{option_results}->{'format_' . $self->{severity}})) {
my $format_value = $self->{instance_mode}->{option_results}->{'format_' . $self->{severity}};
$format_value =~ s/%\{value\}/$value/g;
$format_value =~ s/%\{(.*?)\}/$format_value->{$1}/g;
$value = $format_value;
}
return $value;
}
sub custom_stringvalue_threshold {
my ($self, %options) = @_;
my $severity = 'ok';
foreach my $check_severity (('critical', 'warning', 'unknown')) {
next if (centreon::plugins::misc::is_empty($self->{option_results}->{$check_severity . '_regexp'}));
my $regexp = $self->{option_results}->{$check_severity . '_regexp'};
if (defined($self->{option_results}->{use_iregexp}) && $options{value} =~ /$regexp/i) {
$severity = $check_severity;
} elsif (!defined($self->{option_results}->{use_iregexp}) && $options{value} =~ /$regexp/) {
$severity = $check_severity;
}
}
$self->{severity} = $severity;
return $severity;
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0 }
];
$self->{maps_counters}->{global} = [
{ label => 'generic',
set => {
key_values => [{ name => 'stringvalue' }],
closure_custom_output => $self->can('custom_stringvalue_output'),
closure_custom_threshold_check => \&custom_stringvalue_threshold
}
}
];
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
if (centreon::plugins::misc::is_empty($options{option_results}->{topic})) {
$self->{output}->add_option_msg(short_msg => 'Missing parameter --topic.');
$self->{output}->option_exit();
}
}
sub manage_selection {
my ($self, %options) = @_;
my $value = $options{mqtt}->query(
topic => $self->{option_results}->{topic}
);
if (!centreon::plugins::misc::is_empty($self->{option_results}->{format_custom})) {
if ($value =~ /$self->{option_results}->{format_custom}/ && defined($1)) {
$value = $1;
}
}
if (!defined($value)) {
$self->{output}->add_option_msg(short_msg => "Cannot find information");
$self->{output}->option_exit();
}
$self->{global} = { stringvalue => $value };
}
1;
__END__
=head1 MODE
Check an Eclipse Mosquitto MQTT topic value against regular expression.
=over 8
=item B<--topic>
Topic value to check.
=item B<--format-custom>
Apply a custom change on the value.
=item B<--warning-regexp>
Return Warning if the topic value match the regexp.
=item B<--critical-regexp>
Return Critical if the topic value match the regexp.
=item B<--regexp-insensitive>
Allows to use case-insensitive regexp.
=item B<--format-*>
Output format according to the threshold.
Can be:
'ok' (default: 'value: %{value}'),
'warning' (default: 'value: %{value}'),
'critical' (default: 'value: %{value}'),
'unknown' (default: 'value: %{value}').
=item B<--format-custom>
Apply a custom change on the value.
=back
=cut

View File

@ -0,0 +1,153 @@
#
# 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 apps::eclipse::mosquitto::mqtt::mode::uptime;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
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_long = { s => 'seconds', w => 'weeks', d => 'days', h => 'hours', m => 'minutes' };
sub custom_uptime_output {
my ($self, %options) = @_;
return sprintf(
'uptime is: %s',
centreon::plugins::misc::change_seconds(value => $self->{result_values}->{uptime}, start => 'd')
);
}
sub custom_uptime_perfdata {
my ($self, %options) = @_;
$self->{output}->perfdata_add(
label => 'uptime', unit => $self->{instance_mode}->{option_results}->{unit},
nlabel => 'system.uptime.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{unit} },
value => floor($self->{result_values}->{uptime} / $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_uptime_threshold {
my ($self, %options) = @_;
return $self->{perfdata}->threshold_check(
value => floor($self->{result_values}->{uptime} / $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 set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0 }
];
$self->{maps_counters}->{global} = [
{ label => 'uptime',
set => {
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')
}
}
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$options{options}->add_options(arguments => {
'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 manage_selection {
my ($self, %options) = @_;
my $topic = '$SYS/broker/uptime';
my $uptime = $options{mqtt}->query(
topic => $topic
);
if ($uptime =~ /^(\d+) seconds$/) {
$uptime = $1;
}
if (centreon::plugins::misc::is_empty($uptime)) {
$self->{output}->add_option_msg(short_msg => "Cannot find uptime information");
$self->{output}->option_exit();
}
$self->{global} = { uptime => $uptime };
}
1;
__END__
=head1 MODE
Check system uptime.
=over 8
=item B<--warning-uptime>
Warning threshold.
=item B<--critical-uptime>
Critical threshold.
=item B<--unit>
Select the time unit for thresholds. May be 's' for seconds, 'm' for minutes, 'h' for hours, 'd' for days, 'w' for weeks. Default is seconds.
=back
=cut

View File

@ -0,0 +1,52 @@
#
# 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 apps::eclipse::mosquitto::mqtt::plugin;
use strict;
use warnings;
use base qw(centreon::plugins::script_mqtt);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$self->{version} = '1.0';
$self->{modes} = {
'uptime' => 'apps::eclipse::mosquitto::mqtt::mode::uptime',
'clients' => 'apps::eclipse::mosquitto::mqtt::mode::clients',
'messages' => 'apps::eclipse::mosquitto::mqtt::mode::messages',
'numeric-value' => 'apps::eclipse::mosquitto::mqtt::mode::numericvalue',
'string-value' => 'apps::eclipse::mosquitto::mqtt::mode::stringvalue'
};
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check Eclipse Mosquitto using MQTT.
=cut

View File

@ -50,6 +50,7 @@ sub new {
'proto:s' => { name => 'proto' }, 'proto:s' => { name => 'proto' },
'warning-http-status:s' => { name => 'warning_http_status' }, 'warning-http-status:s' => { name => 'warning_http_status' },
'auth-method:s' => { name => 'auth_method', default => 'token' }, 'auth-method:s' => { name => 'auth_method', default => 'token' },
'auth-path:s' => { name => 'auth_path' },
'auth-settings:s%' => { name => 'auth_settings' }, 'auth-settings:s%' => { name => 'auth_settings' },
'unknown-http-status:s' => { name => 'unknown_http_status' }, 'unknown-http-status:s' => { name => 'unknown_http_status' },
'vault-token:s' => { name => 'vault_token'} 'vault-token:s' => { name => 'vault_token'}
@ -80,6 +81,10 @@ sub check_options {
$self->{output}->option_exit(); $self->{output}->option_exit();
}; };
if (defined($options{option_results}->{auth_path})) {
$self->{auth_path} = lc($options{option_results}->{auth_path});
};
$self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : ''; $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : '';
$self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 8200; $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 8200;
$self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'http'; $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'http';
@ -151,7 +156,10 @@ sub get_access_token {
my $decoded; my $decoded;
my $login = $self->parse_auth_method(method => $self->{auth_method}, settings => $self->{auth_settings}); my $login = $self->parse_auth_method(method => $self->{auth_method}, settings => $self->{auth_settings});
my $post_json = JSON::XS->new->utf8->encode($login); my $post_json = JSON::XS->new->utf8->encode($login);
my $url_path = '/' . $self->{api_version} . '/auth/'. $self->{auth_method} . '/login/'; if (!defined($self->{auth_path}) || $self->{auth_path} eq '') {
$self->{auth_path} = $self->{auth_method};
}
my $url_path = '/' . $self->{api_version} . '/auth/'. $self->{auth_path} . '/login/';
$url_path .= $self->{auth_settings}->{username} if (defined($self->{auth_settings}->{username}) && $self->{auth_method} =~ 'userpass|login') ; $url_path .= $self->{auth_settings}->{username} if (defined($self->{auth_settings}->{username}) && $self->{auth_method} =~ 'userpass|login') ;
my $content = $self->{http}->request( my $content = $self->{http}->request(
@ -284,6 +292,12 @@ Specify the Vault authentication specific settings.
Syntax: --auth-settings='<setting>=<value>'.Example for the 'userpass' method: Syntax: --auth-settings='<setting>=<value>'.Example for the 'userpass' method:
--auth-method='userpass' --auth-settings='username=my_account' --auth-settings='password=my_password' --auth-method='userpass' --auth-settings='username=my_account' --auth-settings='password=my_password'
=item B<--auth-path>
Authentication path for 'userpass'. Is an optional setting.
More information here: https://developer.hashicorp.com/vault/docs/auth/userpass#configuration
=item B<--timeout> =item B<--timeout>
Set timeout in seconds (default: 10). Set timeout in seconds (default: 10).

View File

@ -29,7 +29,7 @@ use JSON::XS;
sub new { sub new {
my ($class, %options) = @_; my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options); my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class; bless $self, $class;
if (!defined($options{output})) { if (!defined($options{output})) {
@ -42,12 +42,12 @@ sub new {
} }
if (!defined($options{noptions})) { if (!defined($options{noptions})) {
$options{options}->add_options(arguments => { $options{options}->add_options(arguments => {
'hostname:s' => { name => 'hostname' }, 'hostname:s' => { name => 'hostname' },
'port:s' => { name => 'port'}, 'port:s' => { name => 'port' },
'proto:s' => { name => 'proto' }, 'proto:s' => { name => 'proto' },
'api-password:s' => { name => 'api_password' }, 'api-password:s' => { name => 'api_password' },
'timeout:s' => { name => 'timeout', default => 30 }, 'timeout:s' => { name => 'timeout'},
'unknown-http-status:s' => { name => 'unknown_http_status' }, 'unknown-http-status:s' => { name => 'unknown_http_status' },
'warning-http-status:s' => { name => 'warning_http_status' }, 'warning-http-status:s' => { name => 'warning_http_status' },
'critical-http-status:s' => { name => 'critical_http_status' } 'critical-http-status:s' => { name => 'critical_http_status' }
@ -57,7 +57,7 @@ sub new {
$options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1);
$self->{output} = $options{output}; $self->{output} = $options{output};
$self->{http} = centreon::plugins::http->new(%options); $self->{http} = centreon::plugins::http->new(%options);
return $self; return $self;
} }
@ -73,14 +73,14 @@ sub set_defaults {}
sub check_options { sub check_options {
my ($self, %options) = @_; my ($self, %options) = @_;
$self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : ''; $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : '';
$self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 443; $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 443;
$self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https'; $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https';
$self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 30; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 30;
$self->{ssl_opt} = (defined($self->{option_results}->{ssl_opt})) ? $self->{option_results}->{ssl_opt} : undef; $self->{ssl_opt} = (defined($self->{option_results}->{ssl_opt})) ? $self->{option_results}->{ssl_opt} : undef;
$self->{api_password} = (defined($self->{option_results}->{api_password})) ? $self->{option_results}->{api_password} : ''; $self->{api_password} = (defined($self->{option_results}->{api_password})) ? $self->{option_results}->{api_password} : '';
$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->{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->{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} : ''; $self->{critical_http_status} = (defined($self->{option_results}->{critical_http_status})) ? $self->{option_results}->{critical_http_status} : '';
if ($self->{hostname} eq '') { if ($self->{hostname} eq '') {
@ -99,10 +99,10 @@ sub build_options_for_httplib {
my ($self, %options) = @_; my ($self, %options) = @_;
$self->{option_results}->{hostname} = $self->{hostname}; $self->{option_results}->{hostname} = $self->{hostname};
$self->{option_results}->{port} = $self->{port}; $self->{option_results}->{port} = $self->{port};
$self->{option_results}->{proto} = $self->{proto}; $self->{option_results}->{proto} = $self->{proto};
$self->{option_results}->{ssl_opt} = $self->{ssl_opt}; $self->{option_results}->{ssl_opt} = $self->{ssl_opt};
$self->{option_results}->{timeout} = $self->{timeout}; $self->{option_results}->{timeout} = $self->{timeout};
} }
sub settings { sub settings {
@ -119,9 +119,9 @@ sub request_api {
$self->settings(); $self->settings();
my $content = $self->{http}->request( my $content = $self->{http}->request(
%options, %options,
unknown_status => $self->{unknown_http_status}, unknown_status => $self->{unknown_http_status},
warning_status => $self->{warning_http_status}, warning_status => $self->{warning_http_status},
critical_status => $self->{critical_http_status} critical_status => $self->{critical_http_status}
); );
@ -145,8 +145,8 @@ sub internal_search {
my ($self, %options) = @_; my ($self, %options) = @_;
my $status = $self->request_api( my $status = $self->request_api(
method => 'GET', method => 'GET',
url_path => '/apiv2/search', url_path => '/apiv2/search',
get_param => [ get_param => [
'size=1', 'size=1',
'from=-' . $options{time_period} . 'm', 'from=-' . $options{time_period} . 'm',
@ -160,8 +160,8 @@ sub internal_events {
my ($self, %options) = @_; my ($self, %options) = @_;
my $status = $self->request_api( my $status = $self->request_api(
method => 'GET', method => 'GET',
url_path => '/apiv2/events', url_path => '/apiv2/events',
get_param => ['rsid=' . $options{id}] get_param => ['rsid=' . $options{id}]
); );
return $status; return $status;
@ -172,7 +172,7 @@ sub api_events {
my $id = $self->internal_search( my $id = $self->internal_search(
time_period => $options{time_period}, time_period => $options{time_period},
query => $options{query} query => $options{query}
); );
my $status = $self->internal_events(id => $id); my $status = $self->internal_events(id => $id);
@ -207,8 +207,8 @@ sub internal_fields {
# 300 limitation comes from the API : https://documentation.solarwinds.com/en/Success_Center/loggly/Content/admin/api-retrieving-data.htm # 300 limitation comes from the API : https://documentation.solarwinds.com/en/Success_Center/loggly/Content/admin/api-retrieving-data.htm
my $status = $self->request_api( my $status = $self->request_api(
method => 'GET', method => 'GET',
url_path => '/apiv2/fields/' . $options{field} . '/', url_path => '/apiv2/fields/' . $options{field} . '/',
get_param => [ get_param => [
'facet_size=300', 'facet_size=300',
'from=-' . $options{time_period} . 'm', 'from=-' . $options{time_period} . 'm',
@ -223,12 +223,12 @@ sub api_fields {
my $status = $self->internal_fields( my $status = $self->internal_fields(
time_period => $options{time_period}, time_period => $options{time_period},
field => $options{field}, field => $options{field},
query => $options{query} query => $options{query}
); );
# Fields may be messed-up with wrongly encoded characters, let's force some cleanup # Fields may be messed-up with wrongly encoded characters, let's force some cleanup
for (my $i = 0; $i < scalar(@{$status->{ $options{field} }}); $i++) { for (my $i = 0 ; $i < scalar(@{$status->{ $options{field} }}) ; $i++) {
$status->{ $options{field} }->[$i]->{term} =~ s/[\r\n]//g; $status->{ $options{field} }->[$i]->{term} =~ s/[\r\n]//g;
$status->{ $options{field} }->[$i]->{term} =~ s/^\s+|\s+$//g; $status->{ $options{field} }->[$i]->{term} =~ s/^\s+|\s+$//g;
} }

View File

@ -34,19 +34,19 @@ sub set_counters {
$self->{maps_counters}->{global} = [ $self->{maps_counters}->{global} = [
{ label => 'events', nlabel => 'events.count', set => { { label => 'events', nlabel => 'events.count', set => {
key_values => [ { name => 'events' } ], key_values => [{ name => 'events' }],
output_template => 'Matching events: %s', output_template => 'Matching events: %s',
perfdatas => [ perfdatas => [
{ template => '%s', value => 'events', min => 0 } { template => '%s', value => 'events', min => 0 }
] ]
} }
} }
]; ];
} }
sub new { sub new {
my ($class, %options) = @_; my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class; bless $self, $class;
$self->{version} = '1.0'; $self->{version} = '1.0';
@ -77,8 +77,8 @@ sub manage_selection {
my ($self, %options) = @_; my ($self, %options) = @_;
my $results = $options{custom}->api_events( my $results = $options{custom}->api_events(
time_period => $self->{option_results}->{time_period}, time_period => $self->{option_results}->{time_period},
query => $self->{option_results}->{query}, query => $self->{option_results}->{query},
output_field => $self->{option_results}->{output_field} output_field => $self->{option_results}->{output_field}
); );
$self->{global} = { events => $results->{total_events} }; $self->{global} = { events => $results->{total_events} };
@ -99,11 +99,11 @@ Count events matching the query.
=item B<--time-period> =item B<--time-period>
Set request period, in minutes. Set request period, in minutes (mandatory option).
=item B<--query> =item B<--query>
Set the query. Set the query (mandatory option).
=item B<--output-field> =item B<--output-field>

View File

@ -35,31 +35,31 @@ sub set_counters {
$self->{maps_counters}->{global} = [ $self->{maps_counters}->{global} = [
{ label => 'events', nlabel => 'events.count', display_ok => 1, set => { { label => 'events', nlabel => 'events.count', display_ok => 1, set => {
key_values => [ { name => 'events' } ], key_values => [{ name => 'events' }],
output_template => 'Matching events: %s', output_template => 'Matching events: %s',
perfdatas => [ perfdatas => [
{ template => '%s', min => 0 } { template => '%s', min => 0 }
] ]
} }
}, },
{ label => 'fields', nlabel => 'fields.count', display_ok => 1, set => { { label => 'fields', nlabel => 'fields.count', display_ok => 1, set => {
key_values => [ { name => 'fields' } ], key_values => [{ name => 'fields' }],
output_template => 'Matching fields: %s', output_template => 'Matching fields: %s',
perfdatas => [ perfdatas => [
{ template => '%s', min => 0 } { template => '%s', min => 0 }
] ]
} }
}, },
]; ];
$self->{maps_counters}->{field} = [ $self->{maps_counters}->{field} = [
{ label => 'field-events', nlabel => 'field.events.count', set => { { label => 'field-events', nlabel => 'field.events.count', set => {
key_values => [ { name => 'count' }, { name => 'display' } ], key_values => [{ name => 'count' }, { name => 'display' }],
output_template => 'matching events: %s', output_template => 'matching events: %s',
perfdatas => [ perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'display' } { template => '%s', min => 0, label_extra_instance => 1, instance_use => 'display' }
] ]
} }
} }
]; ];
} }
@ -72,7 +72,7 @@ sub prefix_field_output {
sub new { sub new {
my ($class, %options) = @_; my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class; bless $self, $class;
$self->{version} = '1.0'; $self->{version} = '1.0';
@ -118,8 +118,8 @@ sub manage_selection {
my $results = $options{custom}->api_fields( my $results = $options{custom}->api_fields(
time_period => $self->{option_results}->{time_period}, time_period => $self->{option_results}->{time_period},
query => $self->{option_results}->{query}, query => $self->{option_results}->{query},
field => $self->{option_results}->{field} field => $self->{option_results}->{field}
); );
my ($events, $fields) = (0, 0); my ($events, $fields) = (0, 0);
@ -128,10 +128,10 @@ sub manage_selection {
foreach (@{$results->{$self->{option_results}->{field}}}) { foreach (@{$results->{$self->{option_results}->{field}}}) {
if (!defined($self->{option_results}->{filter_field}) || ($_->{term} =~ /$self->{option_results}->{filter_field}/i)) { if (!defined($self->{option_results}->{filter_field}) || ($_->{term} =~ /$self->{option_results}->{filter_field}/i)) {
$fields++; $fields++;
$events += $_->{count}; $events+= $_->{count};
$self->{field}->{$fields} = { $self->{field}->{$fields} = {
display => $_->{term}, display => $_->{term},
count => $_->{count} count => $_->{count}
}; };
} }
} }
@ -151,19 +151,19 @@ Count unique field-values from events matching the query.
=item B<--time-period> =item B<--time-period>
Set request period, in minutes. Set request period, in minutes (mandatory option).
=item B<--query> =item B<--query>
Set the query. Set the query (mandatory option).
=item B<--field> =item B<--field>
Set the field to count unique values for (example: json.host). Set the field to count unique values for example: json.host (mandatory option).
=item B<--filter-field> =item B<--filter-field>
Set the a field filter. Define which fields should be counted. This option will be treated as a regular expression. If this option is empty, all fields will be counted.
=item B<--warning-*> B<--critical-*> =item B<--warning-*> B<--critical-*>

View File

@ -26,11 +26,11 @@ use base qw(centreon::plugins::script_custom);
sub new { sub new {
my ($class, %options) = @_; my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options); my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class; bless $self, $class;
$self->{version} = '1.0'; $self->{version} = '1.0';
$self->{modes} = { $self->{modes} = {
'events' => 'apps::monitoring::loggly::restapi::mode::events', 'events' => 'apps::monitoring::loggly::restapi::mode::events',
'fields' => 'apps::monitoring::loggly::restapi::mode::fields' 'fields' => 'apps::monitoring::loggly::restapi::mode::fields'
}; };

View File

@ -87,7 +87,7 @@ sub custom_select_output {
if (defined($format)) { if (defined($format)) {
return sprintf( return sprintf(
$format->{printf_msg}, @{$format->{printf_var}} $format->{printf_msg}, @{$format->{printf_var}}
); );
} }
@ -123,7 +123,7 @@ sub new {
my ($class, %options) = @_; my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class; bless $self, $class;
$options{options}->add_options(arguments => { $options{options}->add_options(arguments => {
'config:s' => { name => 'config' }, 'config:s' => { name => 'config' },
'filter-selection:s%' => { name => 'filter_selection' }, 'filter-selection:s%' => { name => 'filter_selection' },
@ -192,7 +192,7 @@ sub get_map_value {
my ($self, %options) = @_; my ($self, %options) = @_;
return undef if ( return undef if (
!defined($self->{config}->{mapping}) || !defined($self->{config}->{mapping}) ||
!defined($self->{config}->{mapping}->{ $options{map} }) !defined($self->{config}->{mapping}->{ $options{map} })
); );
return '' if (!defined($self->{config}->{mapping}->{ $options{map} }->{ $options{value} })); return '' if (!defined($self->{config}->{mapping}->{ $options{map} }->{ $options{value} }));
@ -254,8 +254,9 @@ sub get_payload {
sub call_http { sub call_http {
my ($self, %options) = @_; my ($self, %options) = @_;
if (!defined($options{rq}->{hostname}) || $options{rq}->{hostname} eq '') { if ((!defined($options{rq}->{full_url}) || $options{rq}->{full_url} eq '') &&
$self->{output}->add_option_msg(short_msg => "hostname attribute is missing [http > requests > $options{rq}->{name}]"); (!defined($options{rq}->{hostname}) || $options{rq}->{hostname} eq '')) {
$self->{output}->add_option_msg(short_msg => "hostname or full_url attribute is missing [http > requests > $options{rq}->{name}]");
$self->{output}->option_exit(); $self->{output}->option_exit();
} }
if (!defined($options{rq}->{rtype}) || $options{rq}->{rtype} !~ /^(?:txt|json|xml)$/) { if (!defined($options{rq}->{rtype}) || $options{rq}->{rtype} !~ /^(?:txt|json|xml)$/) {
@ -298,11 +299,19 @@ sub call_http {
$http = centreon::plugins::http->new(noptions => 1, output => $self->{output}); $http = centreon::plugins::http->new(noptions => 1, output => $self->{output});
} }
my $full_url;
my $hostname = $self->substitute_string(value => $options{rq}->{hostname});
if (defined($options{rq}->{full_url}) && $options{rq}->{full_url} ne '') {
$full_url = $self->substitute_string(value => $options{rq}->{full_url});
$hostname = '';
}
my $timing0 = [gettimeofday]; my $timing0 = [gettimeofday];
my ($content) = $http->request( my ($content) = $http->request(
backend => $self->substitute_string(value => $options{rq}->{backend}), http_backend => $self->substitute_string(value => $options{rq}->{backend}),
method => $self->substitute_string(value => $options{rq}->{method}), method => $self->substitute_string(value => $options{rq}->{method}),
hostname => $self->substitute_string(value => $options{rq}->{hostname}), full_url => $full_url,
hostname => $hostname,
proto => $self->substitute_string(value => $options{rq}->{proto}), proto => $self->substitute_string(value => $options{rq}->{proto}),
port => $self->substitute_string(value => $options{rq}->{port}), port => $self->substitute_string(value => $options{rq}->{port}),
url_path => $self->substitute_string(value => $options{rq}->{endpoint}), url_path => $self->substitute_string(value => $options{rq}->{endpoint}),
@ -321,26 +330,6 @@ sub call_http {
$self->add_builtin(name => 'httpCode.' . $options{rq}->{name}, value => $http->get_code()); $self->add_builtin(name => 'httpCode.' . $options{rq}->{name}, value => $http->get_code());
$self->add_builtin(name => 'httpMessage.' . $options{rq}->{name}, value => $http->get_message()); $self->add_builtin(name => 'httpMessage.' . $options{rq}->{name}, value => $http->get_message());
if ($options{rq}->{rtype} eq 'json') {
eval {
$content = JSON::XS->new->utf8->decode($content);
};
} elsif ($options{rq}->{rtype} eq 'xml') {
eval {
$SIG{__WARN__} = sub {};
$content = XMLin($content, ForceArray => $options{rq}->{force_array}, KeyAttr => []);
};
}
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)");
$self->{output}->output_add(long_msg => "$@", debug => 1);
$self->{output}->option_exit();
}
my $encoded = JSON::XS->new->utf8->pretty->encode($content);
$self->{output}->output_add(long_msg => '======> returned JSON structure:', debug => 1);
$self->{output}->output_add(long_msg => "$encoded", debug => 1);
return ($http->get_header(), $content, $http); return ($http->get_header(), $content, $http);
} }
@ -441,8 +430,31 @@ sub parse_structure {
$options{conf}->{path} = $self->substitute_string(value => $options{conf}->{path}); $options{conf}->{path} = $self->substitute_string(value => $options{conf}->{path});
my $content;
if ($options{rtype} eq 'json') {
eval {
$content = JSON::XS->new->utf8->decode($options{content});
};
} elsif ($options{rtype} eq 'xml') {
eval {
$SIG{__WARN__} = sub {};
$content = XMLin($options{content}, ForceArray => $options{force_array}, KeyAttr => []);
};
}
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)");
$self->{output}->output_add(long_msg => "$@", debug => 1);
$self->{output}->option_exit();
}
if ($self->{output}->is_debug()) {
my $encoded = JSON::XS->new->allow_nonref(1)->utf8->pretty->encode($content);
$self->{output}->output_add(long_msg => '======> returned JSON structure:', debug => 1);
$self->{output}->output_add(long_msg => "$encoded", debug => 1);
}
my $jpath = JSON::Path->new($options{conf}->{path}); my $jpath = JSON::Path->new($options{conf}->{path});
my @values = $jpath->values($options{content}); my @values = $jpath->values($content);
my $local = {}; my $local = {};
my $i = 0; my $i = 0;
@ -534,26 +546,50 @@ sub collect_http_tables {
($headers, $content, $http) = $self->call_http(rq => $options{requests}->[$i], http => $options{http}); ($headers, $content, $http) = $self->call_http(rq => $options{requests}->[$i], http => $options{http});
$self->set_builtin(); $self->set_builtin();
next if (!defined($options{requests}->[$i]->{parse})); if (defined($options{requests}->[$i]->{scenario_stopped_first}) && $options{requests}->[$i]->{scenario_stopped_first} &&
$self->check_filter2(filter => $options{requests}->[$i]->{scenario_stopped_first}, values => $self->{expand})) {
my $local;
foreach my $conf (@{$options{requests}->[$i]->{parse}}) {
if ($options{requests}->[$i]->{rtype} eq 'txt') {
$local = $self->parse_txt(name => $options{requests}->[$i]->{name}, headers => $headers, content => $content, conf => $conf);
} else {
$local = $self->parse_structure(name => $options{requests}->[$i]->{name}, content => $content, conf => $conf);
}
}
if (defined($options{requests}->[$i]->{scenario_stopped}) && $options{requests}->[$i]->{scenario_stopped} &&
$self->check_filter2(filter => $options{requests}->[$i]->{scenario_stopped}, values => $self->{expand})) {
$self->{scenario_stopped} = 1; $self->{scenario_stopped} = 1;
if (defined($options{requests}->[$i]->{scenario_retry}) && $options{requests}->[$i]->{scenario_retry} =~ /^true|1$/i) { if (defined($options{requests}->[$i]->{scenario_retry}) && $options{requests}->[$i]->{scenario_retry} =~ /^true|1$/i) {
$self->{scenario_loop}++; $self->{scenario_loop}++;
$self->{scenario_retry} = 1; $self->{scenario_retry} = 1;
} }
} else { } else {
$self->save_local_http_cache(local_http_cache => $local_http_cache, local => $local); my $local = {};
if (defined($options{requests}->[$i]->{parse})) {
foreach my $conf (@{$options{requests}->[$i]->{parse}}) {
my $lentries = {};
if ($options{requests}->[$i]->{rtype} eq 'txt') {
$lentries = $self->parse_txt(name => $options{requests}->[$i]->{name}, headers => $headers, content => $content, conf => $conf);
} else {
$lentries = $self->parse_structure(
name => $options{requests}->[$i]->{name},
content => $content,
conf => $conf,
rtype => $options{requests}->[$i]->{rtype},
force_array => $options{requests}->[$i]->{force_array}
);
}
$local = { %$local, %$lentries };
}
}
$self->set_functions(
section => "http > requests > $options{requests}->[$i]->{name}",
functions => $options{requests}->[$i]->{functions},
default => 1
);
if (defined($options{requests}->[$i]->{scenario_stopped}) && $options{requests}->[$i]->{scenario_stopped} &&
$self->check_filter2(filter => $options{requests}->[$i]->{scenario_stopped}, values => $self->{expand})) {
$self->{scenario_stopped} = 1;
if (defined($options{requests}->[$i]->{scenario_retry}) && $options{requests}->[$i]->{scenario_retry} =~ /^true|1$/i) {
$self->{scenario_loop}++;
$self->{scenario_retry} = 1;
}
} else {
$self->save_local_http_cache(local_http_cache => $local_http_cache, local => $local);
}
} }
} }
@ -625,6 +661,16 @@ sub use_local_http_cache {
} }
} }
my $builtin = $local_http_cache->get(name => 'builtin');
foreach my $name (keys %$builtin) {
$self->add_builtin(name => $name, value => $builtin->{$name});
}
my $local_vars = $local_http_cache->get(name => 'local_vars');
foreach my $name (keys %$local_vars) {
$self->set_local_variable(name => $name, value => $local_vars->{$name});
}
return 1; return 1;
} }
@ -632,12 +678,20 @@ sub save_local_http_cache {
my ($self, %options) = @_; my ($self, %options) = @_;
if (defined($options{local_http_cache})) { if (defined($options{local_http_cache})) {
my $expand = {};
foreach my $name (keys %{$self->{expand}}) {
next if ($name =~ /^(builtin|constants)\./);
$expand->{$name} = $self->{expand}->{$name};
}
$options{local_http_cache}->write( $options{local_http_cache}->write(
data => { data => {
http_collected => { http_collected => {
tables => $options{local}, tables => $options{local},
epoch => time() epoch => time()
} },
builtin => $self->{builtin},
local_vars => $expand
} }
); );
} }
@ -737,6 +791,17 @@ sub display_variables {
} }
} }
} }
foreach my $name (keys %{$self->{expand}}) {
$self->{output}->output_add(
long_msg => sprintf(
' %s = %s',
$name,
$self->{expand}->{$name}
),
debug => 1
);
}
} }
sub collect_http { sub collect_http {
@ -765,6 +830,13 @@ sub collect_http {
$self->collect_http_sampling(); $self->collect_http_sampling();
# can use local_var set for selection/selection_loop
$self->{local_vars} = {};
foreach my $name (keys %{$self->{expand}}) {
next if ($name =~ /^(builtin|constants)\./);
$self->{local_vars}->{$name} = $self->{expand}->{$name};
}
if ($self->{output}->is_debug()) { if ($self->{output}->is_debug()) {
$self->display_variables(); $self->display_variables();
} }
@ -790,6 +862,14 @@ sub get_local_variable {
} }
sub set_local_variables {
my ($self, %options) = @_;
foreach (keys %{$self->{local_vars}}) {
$self->set_local_variable(name => $_, value => $self->{local_vars}->{$_});
}
}
sub set_local_variable { sub set_local_variable {
my ($self, %options) = @_; my ($self, %options) = @_;
@ -934,7 +1014,7 @@ sub parse_http_tables {
($code, $msg_error, $end, $table_label) = $self->parse_forward( ($code, $msg_error, $end, $table_label) = $self->parse_forward(
chars => $options{chars}, chars => $options{chars},
start => $options{start}, start => $options{start},
allowed => '[a-zA-Z0-9_]', allowed => '[a-zA-Z0-9_\-]',
stop => '[).]' stop => '[).]'
); );
if ($code) { if ($code) {
@ -999,7 +1079,7 @@ sub parse_http_tables {
($code, $msg_error, $end, $label) = $self->parse_forward( ($code, $msg_error, $end, $label) = $self->parse_forward(
chars => $options{chars}, chars => $options{chars},
start => $end + 2, start => $end + 2,
allowed => '[a-zA-Z0-9_]', allowed => '[a-zA-Z0-9_\-]',
stop => '[)]' stop => '[)]'
); );
if ($code) { if ($code) {
@ -1039,7 +1119,7 @@ sub parse_special_variable {
my ($code, $msg_error, $end, $label) = $self->parse_forward( my ($code, $msg_error, $end, $label) = $self->parse_forward(
chars => $options{chars}, chars => $options{chars},
start => $start + 2, start => $start + 2,
allowed => '[a-zA-Z0-9\._]', allowed => '[a-zA-Z0-9\._\-]',
stop => '[)]' stop => '[)]'
); );
if ($code) { if ($code) {
@ -1630,6 +1710,7 @@ sub exec_func_capture {
$self->{output}->add_option_msg(short_msg => $self->{current_section} . " special variable type not allowed in save attribute"); $self->{output}->add_option_msg(short_msg => $self->{current_section} . " special variable type not allowed in save attribute");
$self->{output}->option_exit(); $self->{output}->option_exit();
} }
$self->set_special_variable_value(value => $value, %$save); $self->set_special_variable_value(value => $value, %$save);
} }
} }
@ -1707,7 +1788,7 @@ sub prepare_variables {
return undef if (!defined($options{value})); return undef if (!defined($options{value}));
while ($options{value} =~ /%\(([a-zA-Z0-9\.]+?)\)/g) { while ($options{value} =~ /%\(([a-zA-Z0-9\.\-]+?)\)/g) {
next if ($1 =~ /^http\./); next if ($1 =~ /^http\./);
$options{value} =~ s/%\(($1)\)/\$expand->{'$1'}/g; $options{value} =~ s/%\(($1)\)/\$expand->{'$1'}/g;
} }
@ -1721,7 +1802,7 @@ sub check_filter {
return 0 if (!defined($options{filter}) || $options{filter} eq ''); return 0 if (!defined($options{filter}) || $options{filter} eq '');
our $expand = $options{values}; our $expand = $options{values};
$options{filter} =~ s/%\(([a-zA-Z0-9\._:]+?)\)/\$expand->{'$1'}/g; $options{filter} =~ s/%\(([a-zA-Z0-9\._:\-]+?)\)/\$expand->{'$1'}/g;
my $result = $self->{safe}->reval("$options{filter}"); my $result = $self->{safe}->reval("$options{filter}");
if ($@) { if ($@) {
$self->{output}->add_option_msg(short_msg => 'Unsafe code evaluation: ' . $@); $self->{output}->add_option_msg(short_msg => 'Unsafe code evaluation: ' . $@);
@ -1737,7 +1818,7 @@ sub check_filter2 {
return 0 if (!defined($options{filter}) || $options{filter} eq ''); return 0 if (!defined($options{filter}) || $options{filter} eq '');
our $expand = $options{values}; our $expand = $options{values};
$options{filter} =~ s/%\(([a-zA-Z0-9\._:]+?)\)/\$expand->{'$1'}/g; $options{filter} =~ s/%\(([a-zA-Z0-9\._:\-]+?)\)/\$expand->{'$1'}/g;
my $result = $self->{safe}->reval("$options{filter}"); my $result = $self->{safe}->reval("$options{filter}");
if ($@) { if ($@) {
$self->{output}->add_option_msg(short_msg => 'Unsafe code evaluation: ' . $@); $self->{output}->add_option_msg(short_msg => 'Unsafe code evaluation: ' . $@);
@ -1820,6 +1901,7 @@ sub add_selection {
my $config = {}; my $config = {};
$self->{expand} = $self->set_constants(); $self->{expand} = $self->set_constants();
$self->set_builtin(); $self->set_builtin();
$self->set_local_variables();
$self->{expand}->{name} = $_->{name} if (defined($_->{name})); $self->{expand}->{name} = $_->{name} if (defined($_->{name}));
$self->set_functions(section => "selection > $i > functions", functions => $_->{functions}, position => 'before_expand'); $self->set_functions(section => "selection > $i > functions", functions => $_->{functions}, position => 'before_expand');
$self->set_expand_table(section => "selection > $i > expand_table", expand => $_->{expand_table}); $self->set_expand_table(section => "selection > $i > expand_table", expand => $_->{expand_table});
@ -1857,20 +1939,26 @@ sub add_selection_loop {
next if (!defined($_->{source}) || $_->{source} eq ''); next if (!defined($_->{source}) || $_->{source} eq '');
$self->{current_section} = '[selection_loop > ' . $i . ' > source]'; $self->{current_section} = '[selection_loop > ' . $i . ' > source]';
my $result = $self->parse_special_variable(chars => [split //, $_->{source}], start => 0); my $result = $self->parse_special_variable(chars => [split //, $_->{source}], start => 0);
if ($result->{type} != 2) { if ($result->{type} != 2) {
$self->{output}->add_option_msg(short_msg => $self->{current_section} . " special variable type not allowed"); $self->{output}->add_option_msg(short_msg => $self->{current_section} . " special variable type not allowed");
$self->{output}->option_exit(); $self->{output}->option_exit();
} }
next if (!defined($self->{http_collected}->{tables}->{ $result->{table} })); next if (!defined($self->{http_collected}->{tables}->{ $result->{table} }));
foreach my $instance (keys %{$self->{http_collected}->{tables}->{ $result->{table} }}) { foreach my $instance (keys %{$self->{http_collected}->{tables}->{ $result->{table} }}) {
$self->{expand} = $self->set_constants(); $self->{expand} = $self->set_constants();
$self->set_builtin(); $self->set_builtin();
$self->set_local_variables();
$self->{expand}->{ $result->{table} . '.instance' } = $instance; $self->{expand}->{ $result->{table} . '.instance' } = $instance;
foreach my $label (keys %{$self->{http_collected}->{tables}->{ $result->{table} }->{$instance}}) { foreach my $label (keys %{$self->{http_collected}->{tables}->{ $result->{table} }->{$instance}}) {
$self->{expand}->{ $result->{table} . '.' . $label } = $self->{expand}->{ $result->{table} . '.' . $label } =
$self->{http_collected}->{tables}->{ $result->{table} }->{$instance}->{$label}; $self->{http_collected}->{tables}->{ $result->{table} }->{$instance}->{$label};
} }
my $config = {}; my $config = {};
$self->{expand}->{name} = $_->{name} if (defined($_->{name})); $self->{expand}->{name} = $_->{name} if (defined($_->{name}));
$self->set_functions(section => "selection_loop > $i > functions", functions => $_->{functions}, position => 'before_expand'); $self->set_functions(section => "selection_loop > $i > functions", functions => $_->{functions}, position => 'before_expand');

View File

@ -0,0 +1,180 @@
#
# 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 apps::trendmicro::iwsva::snmp::mode::interfaces;
use base qw(snmp_standard::mode::interfaces);
use strict;
use warnings;
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
return $self;
}
1;
__END__
=head1 MODE
Check interfaces.
=over 8
=item B<--add-global>
Check global port statistics (by default if no --add-* option is set).
=item B<--add-status>
Check interface status.
=item B<--add-duplex-status>
Check duplex status (with --warning-status and --critical-status).
=item B<--add-traffic>
Check interface traffic.
=item B<--add-errors>
Check interface errors.
=item B<--add-cast>
Check interface cast.
=item B<--add-speed>
Check interface speed.
=item B<--add-volume>
Check interface data volume between two checks (not supposed to be graphed, useful for BI reporting).
=item B<--check-metrics>
If the expression is true, metrics are checked (default: '%{opstatus} eq "up"').
=item B<--warning-status>
Define the conditions to match for the status to be WARNING.
You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display}
=item B<--critical-status>
Define the conditions to match for the status to be CRITICAL (default: '%{admstatus} eq "up" and %{opstatus} ne "up"').
You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display}
=item B<--warning-*> B<--critical-*>
Thresholds.
Can be: 'total-port', 'total-admin-up', 'total-admin-down', 'total-oper-up', 'total-oper-down',
'in-traffic', 'out-traffic', 'in-error', 'in-discard', 'out-error', 'out-discard',
'in-ucast', 'in-bcast', 'in-mcast', 'out-ucast', 'out-bcast', 'out-mcast',
'speed' (b/s).
=item B<--units-traffic>
Units of thresholds for the traffic (default: 'percent_delta') ('percent_delta', 'bps', 'counter').
=item B<--units-errors>
Units of thresholds for errors/discards (default: 'percent_delta') ('percent_delta', 'percent', 'delta', 'deltaps', 'counter').
=item B<--units-cast>
Units of thresholds for communication types (default: 'percent_delta') ('percent_delta', 'percent', 'delta', 'deltaps', 'counter').
=item B<--nagvis-perfdata>
Display traffic perfdata to be compatible with NagVis widget.
=item B<--interface>
Set the interface (number expected) example: 1,2,... (empty means 'check all interfaces').
=item B<--name>
Allows you to define the interface (in option --interface) by name instead of OID index. The name matching mode supports regular expressions.
=item B<--speed>
Set interface speed for incoming/outgoing traffic (in Mb).
=item B<--speed-in>
Set interface speed for incoming traffic (in Mb).
=item B<--speed-out>
Set interface speed for outgoing traffic (in Mb).
=item B<--map-speed-dsl>
Get interface speed configuration for interface type 'ADSL' and 'VDSL2'.
Syntax: --map-speed-dsl=interface-src-name,interface-dsl-name
E.g: --map-speed-dsl=Et0.835,Et0-vdsl2
=item B<--force-counters64>
Force to use 64 bits counters only. Can be used to improve performance.
=item B<--force-counters32>
Force to use 32 bits counters (even in SNMP version 2c and version 3). Should be used when 64 bits counters are buggy.
=item B<--reload-cache-time>
Time in minutes before reloading cache file (default: 180).
=item B<--oid-filter>
Define the OID to be used to filter interfaces (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr).
=item B<--oid-display>
Define the OID that will be used to name the interfaces (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr).
=item B<--oid-extra-display>
Add an OID to display.
=item B<--display-transform-src> B<--display-transform-dst>
Modify the interface name displayed by using a regular expression.
Example: adding --display-transform-src='eth' --display-transform-dst='ens' will replace all occurrences of 'eth' with 'ens'
=item B<--show-cache>
Display cache interface data.
=back
=cut

View File

@ -0,0 +1,55 @@
#
# 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 apps::trendmicro::iwsva::snmp::plugin;
use strict;
use warnings;
use base qw(centreon::plugins::script_snmp);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$self->{modes} = {
'cpu' => 'snmp_standard::mode::cpu',
'interfaces' => 'apps::trendmicro::iwsva::snmp::mode::interfaces',
'list-interfaces' => 'snmp_standard::mode::listinterfaces',
'list-storages' => 'snmp_standard::mode::liststorages',
'load' => 'snmp_standard::mode::loadaverage',
'memory' => 'snmp_standard::mode::memory',
'storage' => 'snmp_standard::mode::storage',
'swap' => 'snmp_standard::mode::swap',
'tcpcon' => 'snmp_standard::mode::tcpcon'
};
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check TendMicro Iwsva equipments in SNMP.
=cut

View File

@ -0,0 +1,210 @@
#
# 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::plugins::mqtt;
use strict;
use warnings;
use Time::HiRes;
use Net::MQTT::Simple;
use Net::MQTT::Simple::SSL;
sub new {
my ($class, %options) = @_;
my $self = {};
bless $self, $class;
if (!defined($options{noptions}) || $options{noptions} != 1) {
$options{options}->add_options(arguments => {
'hostname|host:s' => { name => 'host' },
'mqtt-port:s' => { name => 'mqtt_port', default => 8883 },
'mqtt-ssl:s' => { name => 'mqtt_ssl', default => 1 },
'mqtt-ca-certificate:s' => { name => 'mqtt_ca_certificate' },
'mqtt-ssl-certificate:s' => { name => 'mqtt_ssl_certificate' },
'mqtt-ssl-key:s' => { name => 'mqtt_ssl_key' },
'mqtt-username:s' => { name => 'mqtt_username' },
'mqtt-password:s' => { name => 'mqtt_password' },
'mqtt-allow-insecure' => { name => 'mqtt_allow_insecure', default => 0 },
'mqtt-timeout:s' => { name => 'mqtt_timeout', default => 5 }
});
$options{options}->add_help(package => __PACKAGE__, sections => 'MQTT GLOBAL OPTIONS');
}
$self->{output} = $options{output};
$self->{connection_set} = 0;
return $self;
}
sub check_options {
my ($self, %options) = @_;
if (!defined($options{option_results}->{host})) {
$self->{output}->add_option_msg(short_msg => 'Missing parameter --hostname.');
$self->{output}->option_exit();
}
$self->{mqtt_host} = $options{option_results}->{host};
$self->{mqtt_port} = defined($options{option_results}->{mqtt_port}) && $options{option_results}->{mqtt_port} =~ /(\d+)/ ? $1 : 8883;
$self->{mqtt_ssl} = $options{option_results}->{mqtt_ssl};
$self->{mqtt_ca_certificate} = $options{option_results}->{mqtt_ca_certificate};
$self->{mqtt_ssl_certificate} = $options{option_results}->{mqtt_ssl_certificate};
$self->{mqtt_ssl_key} = $options{option_results}->{mqtt_ssl_key};
$self->{mqtt_username} = $options{option_results}->{mqtt_username};
$self->{mqtt_password} = $options{option_results}->{mqtt_password};
$self->{mqtt_allow_insecure} = $options{option_results}->{mqtt_allow_insecure};
$self->{mqtt_timeout} = $options{option_results}->{mqtt_timeout};
}
# Prepare the MQTT connection
sub set_mqtt_options {
my ($self, %options) = @_;
if ($self->{connection_set} == 1) {
return;
}
if (!centreon::plugins::misc::is_empty($self->{mqtt_allow_insecure}) && $self->{mqtt_allow_insecure} == 1) {
$ENV{MQTT_SIMPLE_ALLOW_INSECURE_LOGIN} = 1;
}
if (!centreon::plugins::misc::is_empty($self->{mqtt_ssl}) && $self->{mqtt_ssl} == 1) {
$self->{mqtt} = Net::MQTT::Simple::SSL->new($self->{mqtt_host}, {
LocalPort => $self->{mqtt_port},
SSL_ca_file => $self->{mqtt_ca_certificate},
SSL_cert_file => $self->{mqtt_ssl_certificate},
SSL_key_file => $self->{mqtt_ssl_key}
});
} else {
$self->{mqtt} = Net::MQTT::Simple->new($self->{mqtt_host} . ':' . $self->{mqtt_port});
}
$self->{mqtt}->login($self->{mqtt_username}, $self->{mqtt_password}) if (!centreon::plugins::misc::is_empty($self->{mqtt_username}) && !centreon::plugins::misc::is_empty($self->{mqtt_password}));
$self->{connection_set} = 1;
}
# Query a single topic
# Returns the message
# If no message is received, the script will exit with a message indicating that no message was received in the topic
sub query {
my ($self, %options) = @_;
$self->set_mqtt_options(%options);
my %mqtt_received;
my $starttime = Time::HiRes::time();
my $endtime = $starttime + $self->{mqtt_timeout};
$self->{mqtt}->subscribe($options{topic}, sub {
my ($topic, $message) = @_;
$mqtt_received{$topic} = $message;
});
my $messages_received = 0;
while ($messages_received == 0 and Time::HiRes::time() < $endtime) {
$self->{mqtt}->tick(5);
$messages_received = scalar keys %mqtt_received;
}
eval {
$self->{mqtt}->unsubscribe($options{topic});
};
if (%mqtt_received) {
return %mqtt_received{$options{topic}};
} else {
$self->{output}->add_option_msg(short_msg => 'No message in topic: ' . $options{topic});
$self->{output}->option_exit();
}
}
# Query multiple topics
# Returns a hash with the topics as keys and the messages as values
sub queries {
my ($self, %options) = @_;
$self->set_mqtt_options(%options);
my %mqtt_received;
foreach my $topic (@{$options{topics}}) {
my $topic_for_query = defined($options{base_topic}) ? $options{base_topic} . $topic : $topic;
my $result = $self->query(topic => $topic_for_query);
$mqtt_received{$topic} = $result;
}
return %mqtt_received;
}
1;
__END__
=head1 NAME
MQTT global
=head1 SYNOPSIS
MQTT class
=head1 MQTT OPTIONS
=over 8
=item B<--hostname>
Name or address of the host to monitor (mandatory).
=item B<--mqtt-port>
Port used by MQTT (default: 8883).
=item B<--mqtt-ssl>
Use SSL for MQTT connection (default: 1).
=item B<--mqtt-ca-certificate>
CA certificate file.
=item B<--mqtt-ssl-certificate>
Client SSL certificate file.
=item B<--mqtt-ssl-key>
Client SSL key file.
=item B<--mqtt-username>
MQTT username.
=item B<--mqtt-password>
MQTT password.
=item B<--mqtt-allow-insecure>
Allow insecure login (default: 0).
=item B<--mqtt-timeout>
MQTT timeout (default: 5).
=back
=head1 DESCRIPTION
B<MQTT>.
=cut

View File

@ -45,6 +45,7 @@ sub new {
$options{options}->add_options(arguments => { $options{options}->add_options(arguments => {
'auth-method:s' => { name => 'auth_method', default => 'token' }, 'auth-method:s' => { name => 'auth_method', default => 'token' },
'auth-path:s' => { name => 'auth_path' },
'auth-settings:s%' => { name => 'auth_settings' }, 'auth-settings:s%' => { name => 'auth_settings' },
'map-option:s@' => { name => 'map_option' }, 'map-option:s@' => { name => 'map_option' },
'secret-path:s@' => { name => 'secret_path' }, 'secret-path:s@' => { name => 'secret_path' },
@ -66,7 +67,10 @@ sub get_access_token {
my $decoded; my $decoded;
my $login = $self->parse_auth_method(method => $self->{auth_method}, settings => $self->{auth_settings}); my $login = $self->parse_auth_method(method => $self->{auth_method}, settings => $self->{auth_settings});
my $post_json = JSON::XS->new->utf8->encode($login); my $post_json = JSON::XS->new->utf8->encode($login);
my $url_path = '/v1/auth/'. $self->{auth_method} . '/login/'; if (!defined($self->{auth_path}) || $self->{auth_path} eq '') {
$self->{auth_path} = $self->{auth_method};
}
my $url_path = '/v1/auth/'. $self->{auth_path} . '/login/';
$url_path .= $self->{auth_settings}->{username} if (defined($self->{auth_settings}->{username}) && $self->{auth_method} =~ 'userpass|login') ; $url_path .= $self->{auth_settings}->{username} if (defined($self->{auth_settings}->{username}) && $self->{auth_method} =~ 'userpass|login') ;
my $content = $self->{http}->request( my $content = $self->{http}->request(
@ -145,6 +149,10 @@ sub settings {
$self->{output}->option_exit(); $self->{output}->option_exit();
} }
if (defined($options{option_results}->{auth_path})) {
$self->{auth_path} = lc($options{option_results}->{auth_path});
}
$self->{auth_method} = lc($options{option_results}->{auth_method}); $self->{auth_method} = lc($options{option_results}->{auth_method});
$self->{auth_settings} = defined($options{option_results}->{auth_settings}) && $options{option_results}->{auth_settings} ne '' ? $options{option_results}->{auth_settings} : {}; $self->{auth_settings} = defined($options{option_results}->{auth_settings}) && $options{option_results}->{auth_settings} ne '' ? $options{option_results}->{auth_settings} : {};
$self->{vault_address} = $options{option_results}->{vault_address}; $self->{vault_address} = $options{option_results}->{vault_address};
@ -277,6 +285,12 @@ Can be: 'http', 'https' (default: http).
Authentication method to log in against the Vault server. Authentication method to log in against the Vault server.
Can be: 'azure', 'cert', 'github', 'ldap', 'okta', 'radius', 'userpass' (default: 'token'); Can be: 'azure', 'cert', 'github', 'ldap', 'okta', 'radius', 'userpass' (default: 'token');
=item B<--auth-path>
Authentication path for 'userpass'. Is an optional setting.
More information here: https://developer.hashicorp.com/vault/docs/auth/userpass#configuration
=item B<--vault-token> =item B<--vault-token>
Directly specify a valid token to log in (only for --auth-method='token'). Directly specify a valid token to log in (only for --auth-method='token').

View File

@ -0,0 +1,242 @@
#
# 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::plugins::script_mqtt;
use strict;
use warnings;
use centreon::plugins::mqtt;
use centreon::plugins::misc;
sub new {
my ($class, %options) = @_;
my $self = {};
bless $self, $class;
$self->{options} = $options{options};
$self->{output} = $options{output};
$self->{options}->add_options(
arguments => {
'mode:s' => { name => 'mode_name' },
'dyn-mode:s' => { name => 'dynmode_name' },
'list-mode' => { name => 'list_mode' },
'mode-version:s' => { name => 'mode_version' },
'no-sanity-options' => { name => 'no_sanity_options' },
'pass-manager:s' => { name => 'pass_manager' },
}
);
$self->{version} = '1.0';
%{$self->{modes}} = ();
$self->{default} = undef;
$self->{options}->parse_options();
$self->{option_results} = $self->{options}->get_options();
foreach (keys %{$self->{option_results}}) {
$self->{$_} = $self->{option_results}->{$_};
}
$self->{options}->clean();
$self->{options}->add_help(package => $options{package}, sections => 'PLUGIN DESCRIPTION');
$self->{options}->add_help(package => __PACKAGE__, sections => 'GLOBAL OPTIONS');
$self->{output}->mode(name => $self->{mode_name});
return $self;
}
sub init {
my ($self, %options) = @_;
# add meta mode
$self->{modes}->{multi} = 'centreon::plugins::multi';
if (defined($options{help}) && !defined($self->{mode_name}) && !defined($self->{dynmode_name})) {
$self->{options}->display_help();
$self->{output}->option_exit();
}
if (defined($options{version}) && !defined($self->{mode_name}) && !defined($self->{dynmode_name})) {
$self->version();
}
if (defined($self->{list_mode})) {
$self->list_mode();
}
$self->{options}->set_sanity() if (!defined($self->{no_sanity_options}));
# Output HELP
$self->{options}->add_help(package => 'centreon::plugins::output', sections => 'OUTPUT OPTIONS');
$self->load_password_mgr();
# MQTT
$self->{mqtt} = centreon::plugins::mqtt->new(options => $self->{options}, output => $self->{output});
# Load mode
if (defined($self->{mode_name}) && $self->{mode_name} ne '') {
$self->is_mode(mode => $self->{mode_name});
centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $self->{modes}{$self->{mode_name}},
error_msg => "Cannot load module --mode.");
$self->{mode} = $self->{modes}{$self->{mode_name}}->new(options => $self->{options}, output => $self->{output}, mode => $self->{mode_name});
} elsif (defined($self->{dynmode_name}) && $self->{dynmode_name} ne '') {
(undef, $self->{dynmode_name}) = centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $self->{dynmode_name},
error_msg => "Cannot load module --dyn-mode.");
$self->{mode} = $self->{dynmode_name}->new(options => $self->{options}, output => $self->{output}, mode => $self->{dynmode_name});
} else {
$self->{output}->add_option_msg(short_msg => "Need to specify '--mode' or '--dyn-mode' option.");
$self->{output}->option_exit();
}
if (defined($options{help})) {
if (defined($self->{mode_name}) && $self->{mode_name} ne '') {
$self->{options}->add_help(package => $self->{modes}{$self->{mode_name}}, sections => 'MODE');
} else {
$self->{options}->add_help(package => $self->{dynmode_name}, sections => 'MODE');
}
$self->{options}->display_help();
$self->{output}->option_exit();
}
if (defined($options{version})) {
$self->{mode}->version();
$self->{output}->option_exit(nolabel => 1);
}
if (centreon::plugins::misc::minimal_version($self->{mode}->{version}, $self->{mode_version}) == 0) {
$self->{output}->add_option_msg(short_msg => "Not good version for plugin mode. Excepted at least: " . $self->{mode_version} . ". Get: " . $self->{mode}->{version});
$self->{output}->option_exit();
}
$self->{options}->parse_options();
$self->{option_results} = $self->{options}->get_options();
$self->{pass_mgr}->manage_options(option_results => $self->{option_results}) if (defined($self->{pass_mgr}));
$self->{mqtt}->check_options(option_results => $self->{option_results});
$self->{mode}->check_options(
option_results => $self->{option_results},
default => $self->{default},
modes => $self->{modes} # for meta mode multi
);
}
sub load_password_mgr {
my ($self, %options) = @_;
return if (!defined($self->{option_results}->{pass_manager}) || $self->{option_results}->{pass_manager} eq '');
(undef, my $pass_mgr_name) = centreon::plugins::misc::mymodule_load(
output => $self->{output}, module => "centreon::plugins::passwordmgr::" . $self->{option_results}->{pass_manager},
error_msg => "Cannot load module 'centreon::plugins::passwordmgr::" . $self->{option_results}->{pass_manager} . "'"
);
$self->{pass_mgr} = $pass_mgr_name->new(options => $self->{options}, output => $self->{output});
}
sub run {
my $self = shift;
if ($self->{output}->is_disco_format()) {
$self->{mode}->disco_format();
$self->{output}->display_disco_format();
$self->{output}->exit(exit_litteral => 'ok');
}
$self->{mqtt}->set_mqtt_options();
if ($self->{output}->is_disco_show()) {
$self->{mode}->disco_show(snmp => $self->{snmp});
$self->{output}->display_disco_show();
$self->{output}->exit(exit_litteral => 'ok');
} else {
$self->{mode}->run(mqtt => $self->{mqtt});
}
}
sub is_mode {
my ($self, %options) = @_;
# $options->{mode} = mode
if (!defined($self->{modes}{$options{mode}})) {
$self->{output}->add_option_msg(short_msg => "mode '" . $options{mode} . "' doesn't exist (use --list-mode option to show available modes).");
$self->{output}->option_exit();
}
}
sub version {
my $self = shift;
$self->{output}->add_option_msg(short_msg => "Plugin Version: " . $self->{version});
$self->{output}->option_exit(nolabel => 1);
}
sub list_mode {
my $self = shift;
$self->{options}->display_help();
$self->{output}->add_option_msg(long_msg => 'Modes Meta:');
$self->{output}->add_option_msg(long_msg => ' multi');
$self->{output}->add_option_msg(long_msg => '');
$self->{output}->add_option_msg(long_msg => 'Modes Available:');
foreach (sort keys %{$self->{modes}}) {
next if ($_ eq 'multi');
$self->{output}->add_option_msg(long_msg => ' ' . $_);
}
$self->{output}->option_exit(nolabel => 1);
}
1;
__END__
=head1 NAME
-
=head1 SYNOPSIS
-
=head1 GLOBAL OPTIONS
=over 8
=item B<--mode>
Define the mode in which you want the plugin to be executed (see --list-mode).
=item B<--dyn-mode>
Specify a mode with the module's path (advanced).
=item B<--list-mode>
List all available modes.
=item B<--mode-version>
Check minimal version of mode. If not, unknown error.
=item B<--version>
Return the version of the plugin.
=item B<--pass-manager>
Define the password manager you want to use.
Supported managers are: environment, file, keepass, hashicorpvault and teampass.
=back
=head1 DESCRIPTION
B<>.
=cut

View File

@ -102,6 +102,7 @@ sub settings {
# output : deserialized json from the api if not error found in http call. # output : deserialized json from the api if not error found in http call.
sub request_api { sub request_api {
my ($self, %options) = @_; my ($self, %options) = @_;
$self->settings();
# datacore api require a ServerHost header with the hostname used to query the api to respond. # datacore api require a ServerHost header with the hostname used to query the api to respond.
# authentication is http standard basic auth. # authentication is http standard basic auth.

View File

@ -84,7 +84,7 @@ sub manage_selection {
my ($self, %options) = @_; my ($self, %options) = @_;
my $data = $options{custom}->request_api( my $data = $options{custom}->request_api(
url_path => '/RestService/rest.svc/1.0/performances/' . $self->{option_results}->{pool_id}, url_path => '/RestService/rest.svc/1.0/performance/' . $self->{option_results}->{pool_id},
); );
if (defined($data->[1])) { if (defined($data->[1])) {
$self->{output}->add_option_msg(short_msg => 'multiples pools found in api response, only one is expected. Please check pool_id and datacore versions.'); $self->{output}->add_option_msg(short_msg => 'multiples pools found in api response, only one is expected. Please check pool_id and datacore versions.');
@ -100,17 +100,17 @@ __END__
=head1 MODE =head1 MODE
Check Datacore pool space and over subscribed usage exposed through the rest api. Check Datacore pool space and over subscribed usage exposed through the Rest API.
=over 8 =over 8
=item B<--pool-id> =item B<--pool-id>
Id of the pool to check. See list-pool autodiscovery mode to list pools id (required). Id of the pool to check. See list-pool auto discovery mode to list pools id (required).
=item B<--warning-oversubscribed> B<--critical-oversubscribed> =item B<--warning-oversubscribed> B<--critical-oversubscribed>
Warning and critical threshold on the number of Bytes suscribed over the real space of the pool. Warning and critical threshold on the number of Bytes subscribed over the real space of the pool.
=item B<--warning-bytesallocatedpercentage> B<--critical-bytesallocatedpercentage> =item B<--warning-bytesallocatedpercentage> B<--critical-bytesallocatedpercentage>

View File

@ -18,6 +18,6 @@ Start Mockoon
... ${MOCKOON_JSON} ... ${MOCKOON_JSON}
... --port ... --port
... 3000 ... 3000
Sleep 5s Sleep 10s
Stop Mockoon Stop Mockoon
Terminate All Processes Terminate All Processes

View File

@ -1,6 +1,10 @@
--add-sysdesc --add-sysdesc
--api-password
--api-version
--critical-bytesallocatedpercentage
--display-transform-dst --display-transform-dst
--display-transform-src --display-transform-src
--dyn-mode
--exclude-fs --exclude-fs
--filter-fs --filter-fs
--filter-vdom --filter-vdom
@ -8,10 +12,21 @@
--force-counters64 --force-counters64
--force-oid --force-oid
--map-speed-dsl --map-speed-dsl
--mqtt
--mqtt-allow-insecure
--mqtt-ca-certificate
--mqtt-password
--mqtt-port
--mqtt-ssl
--mqtt-ssl-certificate
--mqtt-ssl-key
--mqtt-timeout
--mqtt-username
--nagvis-perfdata --nagvis-perfdata
--oid-display --oid-display
--oid-extra-display --oid-extra-display
--oid-filter --oid-filter
--warning-bytesallocatedpercentage
2c 2c
ADSL ADSL
Avigilon Avigilon
@ -23,6 +38,8 @@ eth
fanspeed fanspeed
Fortigate Fortigate
Fortinet Fortinet
HashiCorp
hashicorpvault
ifAlias ifAlias
ifDesc ifDesc
ifName ifName
@ -31,11 +48,18 @@ in-mcast
in-ucast in-ucast
interface-dsl-name interface-dsl-name
IpAddr IpAddr
Iwsva
keepass
ldap
license-instances-usage-prct license-instances-usage-prct
Loggly
MBean MBean
Mosquitto
MQTT
NagVis NagVis
Netscaler Netscaler
OID OID
okta
oneaccess-sys-mib oneaccess-sys-mib
out-bcast out-bcast
out-mcast out-mcast
@ -51,11 +75,16 @@ SNMP
space-usage-prct space-usage-prct
SSH SSH
SureBackup SureBackup
teampass
timeframe timeframe
topic-messages-inflighted topic-messages-inflighted
total-oper-down total-oper-down
total-oper-up total-oper-up
TendMicro
uptime uptime
userpass
VDSL2 VDSL2
Veeam Veeam
v1
v2
WSMAN WSMAN

View File

@ -0,0 +1,74 @@
*** Settings ***
Documentation Eclipse Mosquitto MQTT plugin tests
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}..${/}resources/import.resource
Test Timeout 120s
Keyword Tags notauto
*** Variables ***
${HOSTNAME} mosquitto_openssl
${MQTT_PORT} 8883
${MQTT_CA_CERTIFICATE} /home/code/tests/robot/apps/eclipse/mosquitto/mqtt/certs/ca.crt
${MQTT_SSL_CERTIFICATE} /home/code/tests/robot/apps/eclipse/mosquitto/mqtt/certs/client.crt
${MQTT_SSL_KEY} /home/code/tests/robot/apps/eclipse/mosquitto/mqtt/certs/client.key
${CMD} ${CENTREON_PLUGINS} --plugin=apps::eclipse::mosquitto::mqtt::plugin --hostname=${HOSTNAME} --mqtt-port=${MQTT_PORT} --mqtt-ca-certificate=${MQTT_CA_CERTIFICATE} --mqtt-ssl-certificate=${MQTT_SSL_CERTIFICATE} --mqtt-ssl-key=${MQTT_SSL_KEY}
*** Test Cases ***
Mosquitto MQTT uptime
[Documentation] Check Mosquitto MQTT uptime
[Tags] eclipse mosquitto mqtt
${command} Catenate
... ${CMD}
... --mode=uptime
... --help
${output} Run ${command}
${output} Strip String ${output}
Mosquitto MQTT clients
[Documentation] Check Mosquitto MQTT uptime
[Tags] eclipse mosquitto mqtt
${command} Catenate
... ${CMD}
... --mode=clients
... --help
${output} Run ${command}
${output} Strip String ${output}
Mosquitto MQTT messages
[Documentation] Check Mosquitto MQTT uptime
[Tags] eclipse mosquitto mqtt
${command} Catenate
... ${CMD}
... --mode=messages
... --help
${output} Run ${command}
${output} Strip String ${output}
Mosquitto MQTT numeric-value
[Documentation] Check Mosquitto MQTT uptime
[Tags] eclipse mosquitto mqtt
${command} Catenate
... ${CMD}
... --mode=numeric-value
... --help
${output} Run ${command}
${output} Strip String ${output}
Mosquitto MQTT string-value
[Documentation] Check Mosquitto MQTT uptime
[Tags] eclipse mosquitto mqtt
${command} Catenate
... ${CMD}
... --mode=string-value
... --help
${output} Run ${command}
${output} Strip String ${output}

View File

@ -0,0 +1,61 @@
{
"constants": {
"protocol": "https",
"port": "443",
"customPath": "centreon"
},
"http": {
"requests": [
{
"name": "authenticationRequest",
"hostname": "%(constants.hostname)",
"proto": "%(constants.protocol)",
"port": "%(constants.port)",
"endpoint": "/%(constants.customPath)/api/latest/login",
"method": "POST",
"headers": [
"Accept:application/json",
"Content-Type:application/json"
],
"timeout": 30,
"payload": {
"type": "json",
"value": {
"security": {
"credentials": {
"login": "%(constants.username)",
"password": "%(constants.password)"
}
}
}
},
"backend": "curl",
"rtype": "json",
"parse": [
{
"name": "token",
"path": "$.security.token",
"entries": [
{
"id": "value"
}
]
}
]
}
]
},
"selection": [
{
"name": "authenticationSelection",
"critical": "defined(%(builtin.httpCode.authenticationRequest)) and %(builtin.httpCode.authenticationRequest) != 200",
"formatting": {
"printf_msg": "Authentication resulted in %s HTTP code",
"printf_var": [
"%(builtin.httpCode.authenticationRequest)"
],
"display_ok": true
}
}
]
}

View File

@ -0,0 +1,160 @@
{
"constants": {
"protocol": "https",
"port": "443",
"customPath": "centreon"
},
"http": {
"requests": [
{
"name": "authenticationRequest",
"hostname": "%(constants.hostname)",
"proto": "%(constants.protocol)",
"port": "%(constants.port)",
"endpoint": "/%(constants.customPath)/api/latest/login",
"method": "POST",
"headers": [
"Accept:application/json",
"Content-Type:application/json"
],
"timeout": 30,
"payload": {
"type": "json",
"value": {
"security": {
"credentials": {
"login": "%(constants.username)",
"password": "%(constants.password)"
}
}
}
},
"scenario_stopped": "%(builtin.httpCode.authenticationRequest) != 200",
"backend": "curl",
"rtype": "json",
"parse": [
{
"name": "token",
"path": "$.security.token",
"entries": [
{
"id": "value"
}
]
}
]
},
{
"name": "resourcesRequest",
"hostname": "%(constants.hostname)",
"proto": "%(constants.protocol)",
"port": "%(constants.port)",
"endpoint": "/%(constants.customPath)/api/latest/monitoring/resources?limit=1000&search={\"information\": {\"$eq\": \"(Execute command failed)\"}}",
"method": "GET",
"headers": [
"X-AUTH-TOKEN: %(http.tables.authenticationRequestToken.[0].value)",
"Accept: text/json"
],
"timeout": 30,
"scenario_stopped": "%(builtin.httpCode.authenticationRequest) != 200",
"backend": "curl",
"rtype": "json",
"parse": [
{
"name": "meta",
"type": "body",
"path": "$.meta",
"entries": [
{
"id": "total"
}
]
},
{
"name": "entries",
"type": "body",
"path": "$.result[*]",
"entries": [
{
"id": "parent.name"
},
{
"id": "name"
},
{
"id": "type"
},
{
"id": "information"
}
]
}
]
}
]
},
"selection_loop": [
{
"name": "HostsLoop",
"source": "%(http.tables.resourcesRequestEntries)",
"filter": "%(resourcesRequestEntries.type) eq 'host'",
"formatting": {
"display_ok": "false",
"printf_msg": "Host %s's output is '%s'",
"printf_var": [
"%(resourcesRequestEntries.name)",
"%(resourcesRequestEntries.information)"
]
},
"warning": "%(resourcesRequestEntries.information) =~ /No output returned from plugin|Execute command failed/"
},
{
"name": "ServicesLoop",
"source": "%(http.tables.resourcesRequestEntries)",
"filter": "%(resourcesRequestEntries.type) eq 'service'",
"formatting": {
"display_ok": "false",
"printf_msg": "Service %s/%s output is '%s'",
"printf_var": [
"%(resourcesRequestEntries.parent.name)",
"%(resourcesRequestEntries.name)",
"%(resourcesRequestEntries.information)"
]
},
"warning": "%(resourcesRequestEntries.information) =~ /No output returned from plugin|Execute command failed/"
}
],
"selection": [
{
"name": "totalSelection",
"functions": [
{
"type": "assign",
"expression": "%(http.tables.resourcesRequestMeta.[0].total)",
"save": "%(brokenCommandsCount)"
}
],
"perfdatas": [
{
"nlabel": "commands.broken.count",
"value": "%(brokenCommandsCount)",
"warning": "0",
"min": 0
}
],
"exit": "%(brokenCommandsCount) == 0",
"warning": "%(brokenCommandsCount) > 0",
"formatting_warning": {
"printf_msg": "",
"display_ok": false,
"separator": " "
},
"formatting": {
"printf_msg": "All commands are fine",
"display_ok": true,
"separator": ""
}
}
]
}

View File

@ -0,0 +1,132 @@
{
"constants": {
"protocol": "https",
"port": "443",
"customPath": "centreon"
},
"http": {
"requests": [
{
"name": "authenticationRequest",
"hostname": "%(constants.hostname)",
"proto": "%(constants.protocol)",
"port": "%(constants.port)",
"endpoint": "/%(constants.customPath)/api/latest/login",
"method": "POST",
"headers": [
"Accept:application/json",
"Content-Type:application/json"
],
"timeout": 30,
"payload": {
"type": "json",
"value": {
"security": {
"credentials": {
"login": "%(constants.username)",
"password": "%(constants.password)"
}
}
}
},
"scenario_stopped": "%(builtin.httpCode.authenticationRequest) != 200",
"backend": "curl",
"rtype": "json",
"parse": [
{
"name": "token",
"path": "$.security.token",
"entries": [
{
"id": "value"
}
]
}
]
},
{
"name": "hostsRequest",
"hostname": "%(constants.hostname)",
"proto": "%(constants.protocol)",
"port": "%(constants.port)",
"endpoint": "/%(constants.customPath)/api/latest/monitoring/hosts?limit=1000",
"method": "GET",
"headers": [
"X-AUTH-TOKEN: %(http.tables.authenticationRequestToken.[0].value)",
"Accept: text/json"
],
"timeout": 30,
"backend": "curl",
"rtype": "json",
"parse": [
{
"name": "entries",
"type": "body",
"path": "$.result[*]",
"entries": [
{
"id": "name"
},
{
"id": "state"
}
]
}
]
}
]
},
"selection": [
{
"name": "authenticationSelection",
"critical": "defined(%(builtin.httpCode.authenticationRequest)) and %(builtin.httpCode.authenticationRequest) != 200",
"exit": "defined(%(builtin.httpCode.authenticationRequest)) and %(builtin.httpCode.authenticationRequest) != 200",
"formatting": {
"printf_msg": "Authentication resulted in %s HTTP code",
"printf_var": [
"%(builtin.httpCode.authenticationRequest)"
],
"display_ok": false
}
},
{
"name": "hostsSelection",
"functions": [
{
"type": "count",
"src": "%(http.tables.hostsRequestEntries)",
"filter": "%(src.state) != 0",
"save": "%(downCount)"
},
{
"type": "count",
"src": "%(http.tables.hostsRequestEntries)",
"save": "%(hostsCount)"
}
],
"perfdatas": [
{
"nlabel": "hostsRequest.down.count",
"value": "%(downCount)",
"warning": "0",
"min": 0,
"max": "%(hostsCount)"
}
],
"warning": "%(downCount) > 0",
"formatting": {
"printf_msg": "Number of down hosts: %s out of %s",
"printf_var": [
"%(downCount)",
"%(hostsCount)"
],
"display_ok": true
}
}
],
"formatting": {
"custom_message_global": "All hosts are UP",
"separator": "-"
}
}

View File

@ -0,0 +1,210 @@
{
"uuid": "919382d8-0f30-447f-abcd-45c98e84d7fe",
"lastMigration": 32,
"name": "Centreon web mock for tests of HTTP Collections",
"endpointPrefix": "",
"latency": 0,
"port": 3001,
"hostname": "",
"folders": [],
"routes": [
{
"uuid": "82abcb5a-0a65-409f-badd-5e881b6786df",
"type": "http",
"documentation": "Authentication request",
"method": "post",
"endpoint": "centreon/api/latest/login",
"responses": [
{
"uuid": "b4229c90-76b3-4f8c-be0f-aceeb5566051",
"body": "{}",
"latency": 0,
"statusCode": 200,
"label": "",
"headers": [
{
"key": "content-type",
"value": "application/json; charset=utf-8"
},
{
"key": "content-length",
"value": "2"
}
],
"bodyType": "DATABUCKET",
"filePath": "",
"databucketID": "0ibb",
"sendFileAsBody": false,
"rules": [],
"rulesOperator": "OR",
"disableTemplating": false,
"fallbackTo404": false,
"default": false,
"crudKey": "id",
"callbacks": []
}
],
"responseMode": null
},
{
"uuid": "d67aa94e-09c5-434d-b00a-e9e147e90220",
"type": "http",
"documentation": "Monitoring of hosts, used to look for down hosts",
"method": "get",
"endpoint": "centreon/api/latest/monitoring/hosts",
"responses": [
{
"uuid": "c98ea5bd-143b-414e-ae28-d094e7059682",
"body": "",
"latency": 0,
"statusCode": 200,
"label": "",
"headers": [
{
"key": "content-security-policy",
"value": "default-src 'none'"
},
{
"key": "content-type",
"value": "text/html; charset=utf-8"
},
{
"key": "x-content-type-options",
"value": "nosniff"
}
],
"bodyType": "DATABUCKET",
"filePath": "",
"databucketID": "fdau",
"sendFileAsBody": false,
"rules": [],
"rulesOperator": "OR",
"disableTemplating": false,
"fallbackTo404": false,
"default": false,
"crudKey": "id",
"callbacks": []
}
],
"responseMode": null
},
{
"uuid": "9622753c-4c89-4f37-aa27-6088a4c5557a",
"type": "http",
"documentation": "Monitoring of resources, used to look for broken commands",
"method": "get",
"endpoint": "centreon/api/latest/monitoring/resources",
"responses": [
{
"uuid": "1d5391f0-9edc-4b84-b9ed-b78524ae1782",
"latency": 0,
"statusCode": 200,
"label": "",
"headers": [
{
"key": "content-security-policy",
"value": "default-src 'none'"
},
{
"key": "content-type",
"value": "text/html; charset=utf-8"
},
{
"key": "x-content-type-options",
"value": "nosniff"
}
],
"bodyType": "DATABUCKET",
"filePath": "",
"databucketID": "tpm8",
"sendFileAsBody": false,
"rules": [],
"rulesOperator": "OR",
"disableTemplating": false,
"fallbackTo404": false,
"default": false,
"crudKey": "id",
"callbacks": [],
"body": "{}"
}
],
"responseMode": null
}
],
"rootChildren": [
{
"type": "route",
"uuid": "82abcb5a-0a65-409f-badd-5e881b6786df"
},
{
"type": "route",
"uuid": "d67aa94e-09c5-434d-b00a-e9e147e90220"
},
{
"type": "route",
"uuid": "9622753c-4c89-4f37-aa27-6088a4c5557a"
}
],
"proxyMode": false,
"proxyHost": "",
"proxyRemovePrefix": false,
"tlsOptions": {
"enabled": false,
"type": "CERT",
"pfxPath": "",
"certPath": "",
"keyPath": "",
"caPath": "",
"passphrase": ""
},
"cors": true,
"headers": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"proxyReqHeaders": [
{
"key": "",
"value": ""
}
],
"proxyResHeaders": [
{
"key": "",
"value": ""
}
],
"data": [
{
"uuid": "497b64fa-7c29-4741-8c57-c818aafc9482",
"id": "fdcz",
"name": "Authentication payload",
"documentation": "Authentication payload",
"value": "{\"security\":{\"credentials\":{\"password\":\"***\",\"login\":\"admin\"}}}"
},
{
"uuid": "e9b76766-90a5-496e-8102-3941d22feb32",
"id": "0ibb",
"name": "Authentication response",
"documentation": "Authentication response",
"value": "{\n \"security\" : {\n \"token\" : \"Vj77k9p53L+FTXon1UDvaYBZU8P3MnUK2siU7mst3HJ1QcnjTDWVW6TX3RlccjpV\"\n },\n \"contact\" : {\n \"name\" : \"Administrateur_Centreon\",\n \"is_admin\" : true,\n \"email\" : \"null@localhost.local\",\n \"alias\" : \"admin\",\n \"id\" : 1\n }\n}"
},
{
"uuid": "18e9cb4a-d822-44cd-b6a3-83dbead20130",
"id": "fdau",
"name": "Monitoring/hosts response",
"documentation": "Monitoring/hosts response to count down hosts",
"value": "{\n \"meta\": {\n \"search\": {},\n \"total\": 1,\n \"limit\": 1000,\n \"sort_by\": {},\n \"page\": 1\n },\n \"result\": [\n {\n \"passive_checks\": false,\n \"timezone\": \"\",\n \"last_check\": \"2023-11-21T21:21:14+01:00\",\n \"checked\": true,\n \"state\": 0,\n \"last_time_up\": \"2023-11-21T21:21:18+01:00\",\n \"icon_image\": \"ppm/applications-monitoring-centreon-central-centreon-128-2.png\",\n \"icon_image_alt\": \"\",\n \"state_type\": 1,\n \"address_ip\": \"127.0.0.1\",\n \"criticality\": null,\n \"last_time_down\": null,\n \"scheduled_downtime_depth\": 0,\n \"name\": \"CENTREON\",\n \"last_time_unreachable\": null,\n \"alias\": \"Centreon Central Server\",\n \"poller_id\": 1,\n \"last_hard_state_change\": \"2023-09-07T20:03:53+02:00\",\n \"execution_time\": 0.112673,\n \"last_state_change\": \"2023-09-07T20:03:53+02:00\",\n \"output\": \"OK - 127.0.0.1 rta 0.079ms lost 0%\\n\",\n \"id\": 13,\n \"max_check_attempts\": 3,\n \"last_update\": \"2023-11-21T08:57:13+01:00\",\n \"acknowledged\": false,\n \"display_name\": \"CENTREON\",\n \"check_attempt\": 1\n }\n ]\n}"
},
{
"uuid": "0fcda655-3209-4726-8ab2-18f93666b57c",
"id": "tpm8",
"name": "Monitoring/resources response",
"documentation": "Monitoring/resources response to check errors in commands",
"value": "{\n \"meta\" : {\n \"page\" : 1,\n \"sort_by\" : {},\n \"search\" : {\n \"$and\" : {\n \"information\" : {\n \"$eq\" : \"(Execute command failed)\"\n }\n }\n },\n \"limit\" : 1000,\n \"total\" : 1\n },\n \"result\" : [\n {\n \"uuid\" : \"h254-s1616\",\n \"host_id\" : 254,\n \"monitoring_server_name\" : \"Central\",\n \"status\" : {\n \"name\" : \"UNKNOWN\",\n \"code\" : 3,\n \"severity_code\" : 3\n },\n \"icon\" : null,\n \"alias\" : null,\n \"last_status_change\" : \"2023-11-22T11:55:30+01:00\",\n \"short_type\" : \"s\",\n \"name\" : \"Svc-BadCommand\",\n \"last_check\" : \"1m 2s\",\n \"duration\" : \"4h 28m\",\n \"acknowledged\" : false,\n \"in_downtime\" : false,\n \"chart_url\" : null,\n \"tries\" : \"1/3 (H)\",\n \"information\" : \"(Execute command failed)\",\n \"performance_data\" : null,\n \"parent\" : {\n \"status\" : {\n \"severity_code\" : 1,\n \"name\" : \"DOWN\",\n \"code\" : 1\n },\n \"host_id\" : null,\n \"uuid\" : \"h254\",\n \"alias\" : \"Down\",\n \"icon\" : null,\n \"links\" : {\n \"externals\" : {\n \"action_url\" : null,\n \"notes\" : null\n },\n \"uris\" : {\n \"configuration\" : null,\n \"reporting\" : null,\n \"logs\" : null\n },\n \"endpoints\" : {}\n },\n \"id\" : 254,\n \"fqdn\" : \"1.2.3.4\",\n \"name\" : \"FakeHostThatIsDown\",\n \"type\" : \"host\",\n \"short_type\" : \"h\",\n \"service_id\" : null\n },\n \"links\" : {\n \"externals\" : {\n \"action_url\" : \"\",\n \"notes\" : {\n \"url\" : \"\",\n \"label\" : \"\"\n }\n },\n \"uris\" : {\n \"logs\" : \"/centreon/main.php?p=20301&svc=254_1616\",\n \"configuration\" : \"/centreon/main.php?p=60201&o=c&service_id=1616\",\n \"reporting\" : \"/centreon/main.php?p=30702&period=yesterday&start=&end=&host_id=254&item=1616\"\n },\n \"endpoints\" : {\n \"check\" : \"/centreon/api/latest/monitoring/hosts/254/services/1616/check\",\n \"acknowledgement\" : \"/centreon/api/latest/monitoring/hosts/254/services/1616/acknowledgements?limit=1\",\n \"timeline\" : \"/centreon/api/latest/monitoring/hosts/254/services/1616/timeline\",\n \"performance_graph\" : null,\n \"downtime\" : \"/centreon/api/latest/monitoring/hosts/254/services/1616/downtimes?search=%7B%22%24and%22:%5B%7B%22start_time%22:%7B%22%24lt%22:1700666614%7D,%22end_time%22:%7B%22%24gt%22:1700666614%7D,%220%22:%7B%22%24or%22:%7B%22is_cancelled%22:%7B%22%24neq%22:1%7D,%22deletion_time%22:%7B%22%24gt%22:1700666614%7D%7D%7D%7D%5D%7D\",\n \"forced_check\" : \"/centreon/api/latest/monitoring/hosts/254/services/1616/check\",\n \"status_graph\" : \"/centreon/api/latest/monitoring/hosts/254/services/1616/metrics/status\",\n \"details\" : \"/centreon/api/latest/monitoring/resources/hosts/254/services/1616\"\n }\n },\n \"passive_checks\" : false,\n \"notification_enabled\" : false,\n \"service_id\" : 1616,\n \"type\" : \"service\",\n \"severity\" : null,\n \"fqdn\" : null,\n \"active_checks\" : true,\n \"id\" : 1616\n }\n ]\n}"
}
],
"callbacks": []
}

View File

@ -0,0 +1,33 @@
*** Settings ***
Documentation Collections of HTTP Protocol plugin testing a mock of Centreon-web API
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}collection-centreon-web.mockoon.json
${CMD} ${CENTREON_PLUGINS} --plugin apps::protocols::http::plugin --mode collection
... --constant='hostname=127.0.0.1' --constant='protocol=http' --constant='port=3000'
... --constant='username=admin' --constant='password=myPassword'
*** Test Cases ***
Check if ${test_desc} on Centreon
[Tags] centreon collections http
${output} Run
... ${CMD} --config=${CURDIR}/${collection}
${output} Strip String ${output}
Should Be Equal As Strings
... ${output}
... ${expected}
... Wrong output result:\n\n ${output}\nInstead of:\n ${expected}\n\n
Examples: test_desc collection expected --
... authentication succeeds collection-centreon-web-check-auth.collection.json OK: Authentication resulted in 200 HTTP code
... hosts are down collection-centreon-web-check-down-hosts.collection.json OK: All hosts are UP | 'hostsRequest.down.count'=0;0;;0;1
... commands are broken collection-centreon-web-check-broken-commands.collection.json WARNING:${SPACE} - Service FakeHostThatIsDown/Svc-BadCommand output is '(Execute command failed)' | 'commands.broken.count'=1;0;;0;

View File

@ -0,0 +1,48 @@
*** Settings ***
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}vault-authentication-hashicorp.json
${CMD} ${CENTREON_PLUGINS} --plugin apps::protocols::snmp::plugin --hostname=127.0.0.1
*** Test Cases ***
check hashicorp vault manager${Name}
[Documentation] Check hashicorp vaultmanager
[Tags] snmp vault
${cmd_hashicorp} Catenate
... ${CMD}
... --pass-manager=hashicorpvault
... --vault-address=127.0.0.1
... --vault-port=3000
... --vault-protocol=http
... --auth-method=userpass
... --auth-settings="username=hcvaultuser"
... --secret-path="path/of/the/secret"
... --snmp-port=2024
... --map-option="snmp_community=\\%{value_path/of/the/secret}"
... --mode=string-value
... --snmp-version=2c
... --snmp-community=apps/protocols/snmp/snmp-single-oid
... --oid='.1.3.6.1.2.1.1.1.0' ${path-param}
... --format-ok='current value is: \\%{details_ok}'
... --format-details-warning='current value is: \\%{details_warning}'
... --format-details-critical='current value is: \\%{details_critical}'
${output} Run
... ${cmd_hashicorp}
${output} Strip String ${output}
Should Be Equal As Strings
... ${output}
... ${result}
... ${cmd_hashicorp}\n\n Wrong output result for hashicorp auth manager on snmp generic plugin, output got :\n${output} \nExpected : \n ${result}\n
Examples: Name path-param result --
... default path --auth-path='' --auth-settings="password=secrethashicorpPassword" OK: current value is: Linux centreon-devbox 5.10.0-28-amd64 #1 SMP Debian 5.10.209-2 (2024-01-31) x86_64
... wrong path --auth-path='specific-url' --auth-settings="password=secrethashicorpPassword" OK: current value is: Linux centreon-devbox 5.10.0-28-amd64 #1 SMP Debian 5.10.209-2 (2024-01-31) x86_64
... wrong password --auth-path='' --auth-settings="password=WrongPassword" UNKNOWN: 401 Unauthorized

View File

@ -0,0 +1 @@
.1.3.6.1.2.1.1.1.0 = STRING: "Linux centreon-devbox 5.10.0-28-amd64 #1 SMP Debian 5.10.209-2 (2024-01-31) x86_64"

View File

@ -0,0 +1,238 @@
{
"uuid": "98b9aab1-da6e-46a5-a2c2-5c001be49806",
"lastMigration": 27,
"name": "Apps hashicorp vault",
"endpointPrefix": "",
"latency": 0,
"port": 3000,
"hostname": "",
"folders": [],
"routes": [
{
"uuid": "6b8dd80b-3ea0-48c0-8e9d-609d618e980e",
"type": "http",
"documentation": "",
"method": "post",
"endpoint": "v1/auth/userpass/login/hcvaultuser",
"responses": [
{
"uuid": "edc924ee-c73b-44e9-8402-d3d75a514083",
"body": "{\r\n \"request_id\":\r\n \"9a423954-2109-1e23-b0e4-f694d557031f\", \"lease_id\":\r\n \"\", \"renewable\":\r\n false, \"lease_duration\":\r\n 0, \"data\":\r\n null, \"wrap_info\":\r\n null, \"warnings\":\r\n [ \"Endpoint replaced the value of these parameters with the values captured from the endpoint's path: [username]\" ], \"auth\":\r\n {\r\n \"client_token\":\r\n \"hvs.CAESIHR511IiIwmAXLTrXQnLJ0Pq-NHQYgfiv4m1ZYVQHVt_Gh4KHGh2cy5HRTZidHZ0b0s3NzE5UG41cE10aUtrQjg\", \"accessor\":\r\n \"fYX782sU7MPQH2Xhf8q0BfSP\", \"policies\":\r\n [ \"default\", \"inf-icinga.ro\" ], \"token_policies\":\r\n [ \"default\", \"inf-icinga.ro\" ], \"metadata\":\r\n {\r\n \"username\":\r\n \"hcvaultuser\"\r\n }, \"lease_duration\":\r\n 604800, \"renewable\":\r\n true, \"entity_id\":\r\n \"cc0f1543-6838-46d1-c97e-d61a5899fc9b\", \"token_type\":\r\n \"service\", \"orphan\":\r\n true, \"mfa_requirement\":\r\n null, \"num_uses\":\r\n 0\r\n }\r\n}",
"latency": 0,
"statusCode": 200,
"label": "if password ok",
"headers": [],
"bodyType": "INLINE",
"filePath": "",
"databucketID": "",
"sendFileAsBody": false,
"rules": [
{
"target": "body",
"modifier": "password",
"value": "secrethashicorpPassword",
"invert": false,
"operator": "equals"
},
{
"target": "body",
"modifier": "username",
"value": "hcvaultuser",
"invert": false,
"operator": "equals"
}
],
"rulesOperator": "AND",
"disableTemplating": false,
"fallbackTo404": false,
"default": false
},
{
"uuid": "fc4cc190-618b-480d-ae22-296248292297",
"body": "{\r\n \"errors\": [\r\n \"wrong user/password\"\r\n ]\r\n}",
"latency": 0,
"statusCode": 401,
"label": "error",
"headers": [],
"bodyType": "INLINE",
"filePath": "",
"databucketID": "",
"sendFileAsBody": false,
"rules": [],
"rulesOperator": "OR",
"disableTemplating": false,
"fallbackTo404": false,
"default": true
}
],
"enabled": true,
"responseMode": null
},
{
"uuid": "8fdb70c1-a874-40eb-8b9f-542dca268992",
"type": "http",
"documentation": "",
"method": "get",
"endpoint": "v1/path/of/the/secret",
"responses": [
{
"uuid": "2dec61d5-f84d-4223-b993-a91d127e0e71",
"body": "{\r\n \"request_id\":\"76aa492b-acc0-52dc-1f2c-3e2f959a5dfd\",\r\n \"lease_id\":\"\",\r\n \"renewable\":false,\r\n \"lease_duration\":0,\r\n \"data\":{\r\n \"data\":{\r\n \"monitor\":\"apps/protocols/snmp/snmp-single-oid\"\r\n },\r\n \"metadata\":{\r\n \"created_time\":\"2023-11-17T13:46:39.240097987Z\",\r\n \"custom_metadata\":null,\r\n \"deletion_time\":\"\",\r\n \"destroyed\":false,\r\n \"version\":1\r\n }\r\n },\r\n \"wrap_info\":null,\r\n \"warnings\":null,\r\n \"auth\":null\r\n}",
"latency": 0,
"statusCode": 200,
"label": "",
"headers": [],
"bodyType": "INLINE",
"filePath": "",
"databucketID": "",
"sendFileAsBody": false,
"rules": [],
"rulesOperator": "OR",
"disableTemplating": false,
"fallbackTo404": false,
"default": true
}
],
"enabled": true,
"responseMode": null
},
{
"uuid": "8ef8c935-ff40-4817-8211-52cc1d0c64b4",
"type": "http",
"documentation": "",
"method": "get",
"endpoint": "v1/otherPath",
"responses": [
{
"uuid": "894d68aa-3f3b-463c-a1dd-cf9dd3565d7c",
"body": "{}",
"latency": 0,
"statusCode": 200,
"label": "",
"headers": [],
"bodyType": "INLINE",
"filePath": "",
"databucketID": "",
"sendFileAsBody": false,
"rules": [],
"rulesOperator": "OR",
"disableTemplating": false,
"fallbackTo404": false,
"default": true
}
],
"enabled": true,
"responseMode": null
},
{
"uuid": "2686745a-9783-4b64-9376-068c159aa725",
"type": "http",
"documentation": "",
"method": "post",
"endpoint": "v1/auth/specific-url/login/hcvaultuser",
"responses": [
{
"uuid": "400e5fea-c3f3-4abc-bc24-73afa75111c6",
"body": "{\r\n \"request_id\":\r\n \"9a423954-2109-1e23-b0e4-f694d557031f\", \"lease_id\":\r\n \"\", \"renewable\":\r\n false, \"lease_duration\":\r\n 0, \"data\":\r\n null, \"wrap_info\":\r\n null, \"warnings\":\r\n [ \"Endpoint replaced the value of these parameters with the values captured from the endpoint's path: [username]\" ], \"auth\":\r\n {\r\n \"client_token\":\r\n \"hvs.CAESIHR511IiIwmAXLTrXQnLJ0Pq-NHQYgfiv4m1ZYVQHVt_Gh4KHGh2cy5HRTZidHZ0b0s3NzE5UG41cE10aUtrQjg\", \"accessor\":\r\n \"fYX782sU7MPQH2Xhf8q0BfSP\", \"policies\":\r\n [ \"default\", \"inf-icinga.ro\" ], \"token_policies\":\r\n [ \"default\", \"inf-icinga.ro\" ], \"metadata\":\r\n {\r\n \"username\":\r\n \"hcvaultuser\"\r\n }, \"lease_duration\":\r\n 604800, \"renewable\":\r\n true, \"entity_id\":\r\n \"cc0f1543-6838-46d1-c97e-d61a5899fc9b\", \"token_type\":\r\n \"service\", \"orphan\":\r\n true, \"mfa_requirement\":\r\n null, \"num_uses\":\r\n 0\r\n }\r\n}",
"latency": 0,
"statusCode": 200,
"label": "if password ok",
"headers": [],
"bodyType": "INLINE",
"filePath": "",
"databucketID": "",
"sendFileAsBody": false,
"rules": [
{
"target": "body",
"modifier": "password",
"value": "secrethashicorpPassword",
"invert": false,
"operator": "equals"
},
{
"target": "body",
"modifier": "username",
"value": "hcvaultuser",
"invert": false,
"operator": "equals"
}
],
"rulesOperator": "AND",
"disableTemplating": false,
"fallbackTo404": false,
"default": false
},
{
"uuid": "21593d10-e496-4a39-ac84-0ef9e0de6bbf",
"body": "{\r\n \"errors\": [\r\n \"wrong user/password\"\r\n ]\r\n}",
"latency": 0,
"statusCode": 401,
"label": "error",
"headers": [],
"bodyType": "INLINE",
"filePath": "",
"databucketID": "",
"sendFileAsBody": false,
"rules": [],
"rulesOperator": "OR",
"disableTemplating": false,
"fallbackTo404": false,
"default": true
}
],
"enabled": true,
"responseMode": null
}
],
"rootChildren": [
{
"type": "route",
"uuid": "6b8dd80b-3ea0-48c0-8e9d-609d618e980e"
},
{
"type": "route",
"uuid": "8fdb70c1-a874-40eb-8b9f-542dca268992"
},
{
"type": "route",
"uuid": "8ef8c935-ff40-4817-8211-52cc1d0c64b4"
},
{
"type": "route",
"uuid": "2686745a-9783-4b64-9376-068c159aa725"
}
],
"proxyMode": false,
"proxyHost": "",
"proxyRemovePrefix": false,
"tlsOptions": {
"enabled": false,
"type": "CERT",
"pfxPath": "",
"certPath": "",
"keyPath": "",
"caPath": "",
"passphrase": ""
},
"cors": true,
"headers": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"proxyReqHeaders": [
{
"key": "",
"value": ""
}
],
"proxyResHeaders": [
{
"key": "",
"value": ""
}
],
"data": []
}

View File

@ -1,133 +0,0 @@
{
"uuid": "e59ad81e-2050-480d-bbae-0e71c607c927",
"lastMigration": 32,
"name": "Aws cloudtrail",
"endpointPrefix": "",
"latency": 0,
"port": 3000,
"hostname": "",
"folders": [],
"routes": [
{
"uuid": "b5e25f3a-a8e3-4128-9e45-f2654c5a599d",
"type": "http",
"documentation": "",
"method": "post",
"endpoint": "cloudtrail/gettrailstatus/:islogging",
"responses": [
{
"uuid": "76483999-2022-4610-8e8c-9c0bd535e4c5",
"body": "{\r\n \"IsLogging\": {{ urlParam 'islogging' 'true' }},\r\n \"LatestCloudWatchLogsDeliveryError\": \"error\",\r\n \"LatestCloudWatchLogsDeliveryTime\": 1683298944.125,\r\n \"LatestDeliveryAttemptSucceeded\": \"2023-05-05T15:02:24Z\",\r\n \"LatestDeliveryAttemptTime\": \"2023-05-05T15:02:24Z\",\r\n \"LatestDeliveryError\": \"error\",\r\n \"LatestDeliveryTime\": 1683298944.125,\r\n \"LatestDigestDeliveryError\": \"error\",\r\n \"LatestDigestDeliveryTime\": 1683298944.125,\r\n \"LatestNotificationAttemptSucceeded\": \"2023-05-05T15:02:24Z\",\r\n \"LatestNotificationAttemptTime\": \"2023-05-05T15:02:24Z\",\r\n \"LatestNotificationError\": \"error\",\r\n \"LatestNotificationTime\": 1683298944.125,\r\n \"StartLoggingTime\": 1683298944.125,\r\n \"StopLoggingTime\": 1683298477.918,\r\n \"TimeLoggingStarted\": \"2023-05-05T15:02:24Z\",\r\n \"TimeLoggingStopped\": \"2023-05-05T14:54:37Z\"\r\n}",
"latency": 0,
"statusCode": 200,
"label": "",
"headers": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"bodyType": "INLINE",
"filePath": "",
"databucketID": "",
"sendFileAsBody": false,
"rules": [],
"rulesOperator": "OR",
"disableTemplating": false,
"fallbackTo404": false,
"default": true,
"crudKey": "id",
"callbacks": []
}
],
"responseMode": null
},
{
"uuid": "77f82f1c-b06e-478a-8366-ab325830f00e",
"type": "http",
"documentation": "",
"method": "post",
"endpoint": "cloudtrail/events/AwsApiCall/:AwsApiCall/AwsServiceEvent/:AwsServiceEvent/AwsConsoleAction/:AwsConsoleAction/AwsConsoleSignIn/:AwsConsoleSignIn/NextToken/:NextToken",
"responses": [
{
"uuid": "7dd41177-8d63-458a-abcc-b3af3ea8c9cd",
"body": "{\r\n\t\"Events\": [\r\n\t\t{{#each (dataRaw 'EventsData')}}\r\n\t\t {{#if (gt @index 0)}}\r\n\t\t ,\r\n\t\t {{/if}}\r\n \t\t{\r\n \t\t\t\"AccessKeyId\": \"{{AccessKeyId}}\",\r\n \t\t\t\"CloudTrailEvent\": \"{\\\"awsRegion\\\": \\\"eu-west-1\\\", {{#if Error}}\\\"errorCode\\\": \\\"{{ErrorCode}}\\\", \\\"errorMessage\\\": \\\"{{ErrorMessage}}\\\",{{/if}} \\\"eventCategory\\\": \\\"Management\\\", \\\"eventID\\\": \\\"{{EventId}}\\\", \\\"eventName\\\": \\\"{{EventName}}\\\", \\\"eventSource\\\": \\\"{{EventSource}}\\\", \\\"eventTime\\\": \\\"{{EventTime}}\\\", \\\"eventType\\\": \\\"{{EventType}}\\\", \\\"eventVersion\\\": \\\"1.08\\\", \\\"managementEvent\\\": true, \\\"readOnly\\\": true, \\\"recipientAccountId\\\": \\\"{{AccountId}}\\\", \\\"requestID\\\": \\\"{{ faker 'string.uuid' }}\\\", \\\"requestParameters\\\": null, \\\"responseElements\\\": null, \\\"sourceIPAddress\\\": \\\"{{ faker 'internet.ip' }}\\\", \\\"tlsDetails\\\": {\\\"cipherSuite\\\": \\\"ECDHE-RSA-AES128-GCM-SHA256\\\", \\\"clientProvidedHostHeader\\\": \\\"cloudtrail.eu-west-1.amazonaws.com\\\", \\\"tlsVersion\\\": \\\"TLSv1.2\\\"}, \\\"userAgent\\\": \\\"aws-cli/2.11.0 Python/3.11.2 Darwin/22.2.0 source/x86_64 prompt/off command/cloudtrail.lookup-events\\\", \\\"userIdentity\\\": {\\\"accessKeyId\\\": \\\"{{AccessKeyId}}\\\", \\\"accountId\\\": \\\"{{AccountId}}\\\", \\\"arn\\\": \\\"arn:aws:sts::{{AccountId}}:assumed-role/{{UserRole}}/{{UserName}}\\\", \\\"principalId\\\": \\\"{{PrincipalId}}:{{UserName}}\\\", \\\"sessionContext\\\": {\\\"attributes\\\": {\\\"creationDate\\\": \\\"{{ faker 'date.past' EventTime }}\\\", \\\"mfaAuthenticated\\\": \\\"false\\\"}, \\\"sessionIssuer\\\": {\\\"accountId\\\": \\\"{{AccountId}}\\\", \\\"arn\\\": \\\"arn:aws:iam::{{AccountId}}:role/{{UserRole}}\\\", \\\"principalId\\\": \\\"{{PrincipalId}}\\\", \\\"type\\\": \\\"Role\\\", \\\"userName\\\": \\\"{{UserRole}}\\\"}, \\\"webIdFederationData\\\": {}}, \\\"type\\\": \\\"{{ faker 'person.jobArea' }}\\\"}}\",\r\n \t\t\t\"EventId\": \"{{EventId}}\",\r\n \t\t\t\"EventName\": \"{{EventName}}\",\r\n \t\t\t\"EventSource\": \"{{EventSource}}\",\r\n \t\t\t\"EventTime\": \"{{EventTime}}\",\r\n \t\t\t\"ReadOnly\": \"true\",\r\n \t\t\t\"Resources\": [\r\n \t\t\t],\r\n \t\t\t\"Username\": \"{{UserName}}\"\r\n \t\t}\r\n\t\t{{/each}}\r\n\t]\r\n\t{{#if (gte (indexOf (urlParam 'NextToken') 'true' 0) 0)}}\r\n\t {{#unless (includes (stringify (body)) 'NextToken')}}\r\n\t\t ,\"NextToken\": \"{{ faker 'string.alphanumeric' 64 casing='upper' }}\"\r\n\t\t{{/unless}}\r\n\t{{/if}}\r\n}",
"latency": 0,
"statusCode": 200,
"label": "",
"headers": [],
"bodyType": "INLINE",
"filePath": "",
"databucketID": "c5kh",
"sendFileAsBody": false,
"rules": [],
"rulesOperator": "OR",
"disableTemplating": false,
"fallbackTo404": false,
"default": true,
"crudKey": "id",
"callbacks": []
}
],
"responseMode": null
}
],
"rootChildren": [
{
"type": "route",
"uuid": "b5e25f3a-a8e3-4128-9e45-f2654c5a599d"
},
{
"type": "route",
"uuid": "77f82f1c-b06e-478a-8366-ab325830f00e"
}
],
"proxyMode": false,
"proxyHost": "",
"proxyRemovePrefix": false,
"tlsOptions": {
"enabled": false,
"type": "CERT",
"pfxPath": "",
"certPath": "",
"keyPath": "",
"caPath": "",
"passphrase": ""
},
"cors": true,
"headers": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"proxyReqHeaders": [
{
"key": "",
"value": ""
}
],
"proxyResHeaders": [
{
"key": "",
"value": ""
}
],
"data": [
{
"uuid": "5dce6340-bade-4336-8041-50fd22570055",
"id": "nu28",
"name": "EventsTypeData",
"documentation": "",
"value": "[\n {\n \"name\": \"AwsApiCall\",\n \"error\": false\n },\n {\n \"name\": \"AwsServiceEvent\",\n \"error\": false\n },\n {\n \"name\": \"AwsConsoleAction\",\n \"error\": true,\n \t\"errorCode\": \"ThrottlingException\",\n \t\"errorMessage\": \"Rate exceeded error\"\n },\n {\n \"name\": \"AwsConsoleSignIn\",\n \"error\": true,\n \"errorCode\": \"LoginErrorException\",\n \"errorMessage\": \"Login error\"\n }\n]"
},
{
"uuid": "76dec2a5-ff63-4e81-9611-94b900ab16e1",
"id": "c5kh",
"name": "EventsData",
"documentation": "",
"value": "[\n {{#each (dataRaw 'EventsTypeData')}}\n {{#if (gte @isEvent 1)}}\n ,\n {{/if}}\n {{setVar 'isEvent' (add (urlParam name) @isEvent)}}\n {{#repeat (urlParam name comma=true)}}\n {\n \"AccessKeyId\": \"{{ faker 'string.alphanumeric' 20 casing='upper' }}\",\n \"AccountId\": \"{{ faker 'string.numeric' 12 }}\",\n \"Error\": {{error}},\n {{#if error}}\n \"ErrorCode\": \"{{errorCode}}\",\n\t \"ErrorMessage\": \"{{errorMessage}}\",\n {{/if}}\n \"EventId\": \"{{ faker 'string.uuid' }}\",\n \"EventName\": \"{{oneOf (array 'LookupEvents' 'ListInstanceAssociations' 'AssumeRoleWithWebIdentity')}}\",\n \"EventSource\": \"{{oneOf (array 'cloudtrail.amazonaws.com' 'ssm.amazonaws.com' 'sts.amazonaws.com')}}\",\n \"EventTime\": \"{{ faker 'date.recent' }}\",\n \"EventType\": \"{{name}}\",\n \"PrincipalId\": \"{{ faker 'string.alphanumeric' 20 casing='upper' }}\",\n \"UserName\": \"{{ faker 'internet.userName' }}\",\n \"UserRole\": \"{{ faker 'person.jobType' }}\"\n }\n {{/repeat}}\n {{/each}}\n]"
}
],
"callbacks": []
}

View File

@ -1,194 +0,0 @@
*** Settings ***
Documentation AWS CloudTrail plugin
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}cloud-aws-cloudtrail.json
${CMD} ${CENTREON_PLUGINS} --plugin=cloud::aws::cloudtrail::plugin --custommode=paws --region=eu-west --aws-secret-key=secret --aws-access-key=key
&{checktrailstatus_value1}
... trailstatus=true
... trailname=TrailName
... result=OK: Trail is logging: 1 | 'trail_is_logging'=1;;;0;
&{checktrailstatus_value2}
... trailstatus=false
... trailname=TrailName
... result=CRITICAL: Trail is logging: 0 | 'trail_is_logging'=0;;;0;
@{checktrailstatus_values} &{checktrailstatus_value1} &{checktrailstatus_value2}
&{countevents_value1}
... AwsApiCall=4
... AwsServiceEvent=2
... AwsConsoleAction=1
... AwsConsoleSignIn=3
... NextToken=false
... eventtype=
... delta=
... errormessage=
... warningcount=
... criticalcount=
... result=OK: Number of events: 10.00 | 'events_count'=10.00;;;0;
&{countevents_value2}
... AwsApiCall=4
... AwsServiceEvent=2
... AwsConsoleAction=1
... AwsConsoleSignIn=3
... NextToken=true
... eventtype=
... delta=
... errormessage=
... warningcount=
... criticalcount=
... result=OK: Number of events: 20.00 | 'events_count'=20.00;;;0;
&{countevents_value3}
... AwsApiCall=4
... AwsServiceEvent=2
... AwsConsoleAction=1
... AwsConsoleSignIn=3
... NextToken=false
... eventtype=AwsApiCall
... delta=
... errormessage=
... warningcount=
... criticalcount=
... result=OK: Number of events: 4.00 | 'events_count'=4.00;;;0;
&{countevents_value4}
... AwsApiCall=4
... AwsServiceEvent=2
... AwsConsoleAction=1
... AwsConsoleSignIn=3
... NextToken=true
... eventtype=AwsServiceEvent
... delta=
... errormessage=
... warningcount=
... criticalcount=
... result=OK: Number of events: 4.00 | 'events_count'=4.00;;;0;
&{countevents_value5}
... AwsApiCall=4
... AwsServiceEvent=2
... AwsConsoleAction=1
... AwsConsoleSignIn=3
... NextToken=false
... eventtype=AwsApiCall
... delta=10
... errormessage=
... warningcount=
... criticalcount=
... result=OK: Number of events: 4.00 | 'events_count'=4.00;;;0;
&{countevents_value6}
... AwsApiCall=4
... AwsServiceEvent=2
... AwsConsoleAction=1
... AwsConsoleSignIn=3
... NextToken=false
... eventtype=
... delta=
... errormessage='Login error'
... warningcount=
... criticalcount=
... result=OK: Number of events: 3.00 | 'events_count'=3.00;;;0;
&{countevents_value7}
... AwsApiCall=4
... AwsServiceEvent=2
... AwsConsoleAction=1
... AwsConsoleSignIn=3
... NextToken=false
... eventtype=
... delta=
... errormessage='.*error'
... warningcount=
... criticalcount=
... result=OK: Number of events: 4.00 | 'events_count'=4.00;;;0;
&{countevents_value8}
... AwsApiCall=4
... AwsServiceEvent=2
... AwsConsoleAction=1
... AwsConsoleSignIn=3
... NextToken=false
... eventtype=
... delta=
... errormessage=
... warningcount=3
... criticalcount=
... result=WARNING: Number of events: 10.00 | 'events_count'=10.00;;;0;
&{countevents_value9}
... AwsApiCall=4
... AwsServiceEvent=2
... AwsConsoleAction=1
... AwsConsoleSignIn=3
... NextToken=false
... eventtype=
... delta=
... errormessage=
... warningcount=
... criticalcount=5
... result=CRITICAL: Number of events: 10.00 | 'events_count'=10.00;;;0;
@{countevents_values}
... &{countevents_value1}
... &{countevents_value2}
... &{countevents_value3}
... &{countevents_value4}
... &{countevents_value5}
... &{countevents_value6}
... &{countevents_value7}
... &{countevents_value8}
... &{countevents_value9}
*** Test Cases ***
AWS CloudTrail check trail status
[Documentation] Check AWS CloudTrail trail status
[Tags] cloud aws cloudtrail
FOR ${checktrailstatus_value} IN @{checktrailstatus_values}
${output} Run
... ${CMD} --mode=checktrailstatus --endpoint=http://localhost:3000/cloudtrail/gettrailstatus/${checktrailstatus_value.trailstatus} --trail-name=${checktrailstatus_value.trailname}
${output} Strip String ${output}
Should Be Equal As Strings
... ${output}
... ${checktrailstatus_value.result}
... Wrong output result for check trail status of ${checktrailstatus_value}.{\n}Command output:{\n}${output}
END
AWS CloudTrail count events
[Documentation] Check AWS CloudTrail count events
[Tags] cloud aws cloudtrail
FOR ${countevents_value} IN @{countevents_values}
${command} Catenate
... ${CMD}
... --mode=countevents
... --endpoint=http://localhost:3000/cloudtrail/events/AwsApiCall/${countevents_value.AwsApiCall}/AwsServiceEvent/${countevents_value.AwsServiceEvent}/AwsConsoleAction/${countevents_value.AwsConsoleAction}/AwsConsoleSignIn/${countevents_value.AwsConsoleSignIn}/NextToken/${countevents_value.NextToken}
${length} Get Length ${countevents_value.eventtype}
IF ${length} > 0
${command} Catenate ${command} --event-type=${countevents_value.eventtype}
END
${length} Get Length ${countevents_value.delta}
IF ${length} > 0
${command} Catenate ${command} --delta=${countevents_value.delta}
END
${length} Get Length ${countevents_value.errormessage}
IF ${length} > 0
${command} Catenate ${command} --error-message=${countevents_value.errormessage}
END
${length} Get Length ${countevents_value.warningcount}
IF ${length} > 0
${command} Catenate ${command} --warning-count=${countevents_value.warningcount}
END
${length} Get Length ${countevents_value.criticalcount}
IF ${length} > 0
${command} Catenate ${command} --critical-count=${countevents_value.criticalcount}
END
${output} Run ${command}
${output} Strip String ${output}
Should Be Equal As Strings
... ${output}
... ${countevents_value.result}
... Wrong output result for count events of ${countevents_value}.{\n}Command output:{\n}${output}
END

View File

@ -12,7 +12,7 @@ Test Timeout 120s
${MOCKOON_JSON} ${CURDIR}${/}cloud-azure-policyinsights-policystates.json ${MOCKOON_JSON} ${CURDIR}${/}cloud-azure-policyinsights-policystates.json
${LOGIN_ENDPOINT} http://localhost:3000/login ${LOGIN_ENDPOINT} http://localhost:3000/login
${CMD} ${CENTREON_PLUGINS} --plugin=cloud::azure::policyinsights::policystates::plugin --subscription=subscription --tenant=tenant --client-id=client_id --client-secret=secret --login-endpoint=${LOGIN_ENDPOINT} ${CMD} ${CENTREON_PLUGINS} --plugin=cloud::azure::policyinsights::policystates::plugin --subscription=subscription --tenant=tenant --client-id=client_id --client-secret=secret --statefile-dir=/tmp/cache/ --login-endpoint=${LOGIN_ENDPOINT}
&{compliance_value1} &{compliance_value1}
... endpoint=http://localhost:3000/ok ... endpoint=http://localhost:3000/ok

View File

@ -35,4 +35,3 @@ Avigilon camera Memory ${tc}/3
... 1 ${EMPTY} ${EMPTY} OK: total system memory available: 464.85 KB | 'memory.available'=476004B;;;0; ... 1 ${EMPTY} ${EMPTY} OK: total system memory available: 464.85 KB | 'memory.available'=476004B;;;0;
... 2 5000 ${EMPTY} WARNING: total system memory available: 464.85 KB | 'memory.available'=476004B;0:5000;;0; ... 2 5000 ${EMPTY} WARNING: total system memory available: 464.85 KB | 'memory.available'=476004B;0:5000;;0;
... 3 ${EMPTY} 5000 CRITICAL: total system memory available: 464.85 KB | 'memory.available'=476004B;;0:5000;0; ... 3 ${EMPTY} 5000 CRITICAL: total system memory available: 464.85 KB | 'memory.available'=476004B;;0:5000;0;

View File

@ -39,4 +39,3 @@ Avigilon camera Temperature ${tc}/5
... 3 ${EMPTY} 20 ${EMPTY} ${EMPTY} CRITICAL: temperature: 23.00 C | 'sensor.temperature.celsius'=23C;;0:20;0; ... 3 ${EMPTY} 20 ${EMPTY} ${EMPTY} CRITICAL: temperature: 23.00 C | 'sensor.temperature.celsius'=23C;;0:20;0;
... 4 ${EMPTY} ${EMPTY} \\%\{status\} =~ /ok/ ${EMPTY} WARNING: sensor 1 [type:mainSensor] status: ok | 'sensor.temperature.celsius'=23C;;;0; ... 4 ${EMPTY} ${EMPTY} \\%\{status\} =~ /ok/ ${EMPTY} WARNING: sensor 1 [type:mainSensor] status: ok | 'sensor.temperature.celsius'=23C;;;0;
... 5 ${EMPTY} ${EMPTY} ${EMPTY} \\%\{status\} =~ /ok/ CRITICAL: sensor 1 [type:mainSensor] status: ok | 'sensor.temperature.celsius'=23C;;;0; ... 5 ${EMPTY} ${EMPTY} ${EMPTY} \\%\{status\} =~ /ok/ CRITICAL: sensor 1 [type:mainSensor] status: ok | 'sensor.temperature.celsius'=23C;;;0;

View File

@ -18,14 +18,14 @@ Cpu-Detailed
[Documentation] cpu-detailed mode [Documentation] cpu-detailed mode
[Tags] hardware kvm avocent cpu snmp [Tags] hardware kvm avocent cpu snmp
Remove File /dev/shm/snmpstandard_127.0.0.1_2024_cpu-detailed* Remove File /dev/shm/snmpstandard_127.0.0.1_2024_cpu-detailed*
${output} Run Avocent 8000 Plugin "cpu-detailed" --statefile-dir=/dev/shm/ ${output} Run Avocent 8000 Plugin "cpu-detailed" --statefile-dir=/tmp/cache/
${output} Strip String ${output} ${output} Strip String ${output}
Should Be Equal As Strings Should Be Equal As Strings
... ${output} ... ${output}
... OK: CPU Usage: user : Buffer creation, nice : Buffer creation, system : Buffer creation, idle : Buffer creation, wait : Buffer creation, kernel : Buffer creation, interrupt : Buffer creation, softirq : Buffer creation, steal : Buffer creation, guest : Buffer creation, guestnice : Buffer creation ... OK: CPU Usage: user : Buffer creation, nice : Buffer creation, system : Buffer creation, idle : Buffer creation, wait : Buffer creation, kernel : Buffer creation, interrupt : Buffer creation, softirq : Buffer creation, steal : Buffer creation, guest : Buffer creation, guestnice : Buffer creation
... Wrong output result for command:{\n}${output}{\n}{\n}{\n} ... Wrong output result for command:{\n}${output}{\n}{\n}{\n}
${output} Run Avocent 8000 Plugin "cpu-detailed" --statefile-dir=/dev/shm/ ${output} Run Avocent 8000 Plugin "cpu-detailed" --statefile-dir=/tmp/cache/
${output} Strip String ${output} ${output} Strip String ${output}
Remove File /dev/shm/snmpstandard_127.0.0.1_2024_cpu-detailed* Remove File /dev/shm/snmpstandard_127.0.0.1_2024_cpu-detailed*
Should Be Equal As Strings Should Be Equal As Strings
@ -70,14 +70,14 @@ Serial Ports
[Documentation] serial-ports mode [Documentation] serial-ports mode
[Tags] hardware kvm avocent serial snmp [Tags] hardware kvm avocent serial snmp
Remove File /dev/shm/avocent_acs_8000_127.0.0.1_2024_serial-ports* Remove File /dev/shm/avocent_acs_8000_127.0.0.1_2024_serial-ports*
${output} Run Avocent 8000 Plugin "serial-ports" --statefile-dir=/dev/shm/ ${output} Run Avocent 8000 Plugin "serial-ports" --statefile-dir=/tmp/cache/
${output} Strip String ${output} ${output} Strip String ${output}
Should Be Equal As Strings Should Be Equal As Strings
... ${output} ... ${output}
... OK: All serial ports are ok ... OK: All serial ports are ok
... Wrong output result for command:{\n}${output}{\n}{\n}{\n} ... Wrong output result for command:{\n}${output}{\n}{\n}{\n}
${output} Run Avocent 8000 Plugin "serial-ports" --statefile-dir=/dev/shm/ ${output} Run Avocent 8000 Plugin "serial-ports" --statefile-dir=/tmp/cache/
${output} Strip String ${output} ${output} Strip String ${output}
Remove File /dev/shm/avocent_acs_8000_127.0.0.1_2024_serial-ports* Remove File /dev/shm/avocent_acs_8000_127.0.0.1_2024_serial-ports*
Should Be Equal As Strings Should Be Equal As Strings

View File

@ -7,7 +7,8 @@ Test Timeout 120s
*** Variables *** *** Variables ***
${CMD} ${CENTREON_PLUGINS} --plugin=network::citrix::netscaler::snmp::plugin ${CMD} ${CENTREON_PLUGINS} --plugin=network::citrix::netscaler::snmp::plugin
*** Test Cases *** *** Test Cases ***
check psu components ${tc}/2 check psu components ${tc}/2
@ -32,5 +33,3 @@ check psu components ${tc}/2
Examples: tc alternative_status_mapping community expected_result -- Examples: tc alternative_status_mapping community expected_result --
... 1 true psu-citrix-v13 OK: All 4 components are ok [4/4 psus]. | 'count_psu'=4;;;; ... 1 true psu-citrix-v13 OK: All 4 components are ok [4/4 psus]. | 'count_psu'=4;;;;
... 2 ${EMPTY} psu-citrix-v13 UNKNOWN: Power supply '1' status is 'not supported' - Power supply '2' status is 'not supported' - Power supply '3' status is 'not supported' - Power supply '4' status is 'not supported' | 'count_psu'=4;;;; ... 2 ${EMPTY} psu-citrix-v13 UNKNOWN: Power supply '1' status is 'not supported' - Power supply '2' status is 'not supported' - Power supply '3' status is 'not supported' - Power supply '4' status is 'not supported' | 'count_psu'=4;;;;

View File

@ -13,7 +13,7 @@ ${CMD} ${CENTREON_PLUGINS}
... --hostname=127.0.0.1 ... --hostname=127.0.0.1
... --snmp-port=2024 ... --snmp-port=2024
... --snmp-community=os/linux/snmp/network-interfaces ... --snmp-community=os/linux/snmp/network-interfaces
... --statefile-dir=/tmp/ ... --statefile-dir=/tmp/cache/
${COND} ${PERCENT}\{sub\} =~ /exited/ && ${PERCENT}{display} =~ /network/' ${COND} ${PERCENT}\{sub\} =~ /exited/ && ${PERCENT}{display} =~ /network/'

View File

@ -32,7 +32,7 @@ Linux SNMP list diskio devices
... --snmp-version=2 ... --snmp-version=2
... --snmp-port=2024 ... --snmp-port=2024
... --disco-show ... --disco-show
${command} Catenate ${command} --snmp-community=${list_diskio_test.snmpcommunity} ... --snmp-community=${list_diskio_test.snmpcommunity}
${output} Run ${command} ${output} Run ${command}
Log To Console ${command} Log To Console ${command}
${nb_results} Get Element Count ${nb_results} Get Element Count

View File

@ -41,7 +41,7 @@
"type": "http", "type": "http",
"documentation": "", "documentation": "",
"method": "get", "method": "get",
"endpoint": "RestService/rest.svc/1.0/performances/B5C140F5-6B13-4CAD-AF9D-F7C4172B3A1D:%7B4dec1b5a-2577-11e5-80c3-00155d651622%7D", "endpoint": "RestService/rest.svc/1.0/performance/B5C140F5-6B13-4CAD-AF9D-F7C4172B3A1D:%7B4dec1b5a-2577-11e5-80c3-00155d651622%7D",
"responses": [ "responses": [
{ {
"uuid": "a5bf53e2-5edf-437e-a684-68315cfa7824", "uuid": "a5bf53e2-5edf-437e-a684-68315cfa7824",