Release 20250114 (#5391)

This commit is contained in:
pkippes 2025-01-14 14:28:49 +01:00 committed by GitHub
commit e34d52c440
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
151 changed files with 91667 additions and 520 deletions

View File

@ -41,7 +41,7 @@ publicly and we'll get in touch with you by private message if this information
- [ ] I have provide data or shown output displaying the result of this code in the plugin area concerned.
------------------------------------------------------------------------------------------------------
# Centreon team
# Centreon team (internal PR)
## Description
@ -75,8 +75,9 @@ Mention the automated tests included in this FOR (what they test like mode/optio
- [ ] I have **rebased** my development branch on the base branch (develop).
- [ ] In case of a new plugin, I have created the new packaging directory accordingly.
- [ ] I have implemented automated tests related to my commits.
- [ ] Data used for automated tests are anonymized.
- [ ] I have reviewed all the help messages in all the .pm files I have modified.
- [ ] All sentences begin with a capital letter.
- [ ] All sentences are terminated by a period.
- [ ] All sentences end with a period.
- [ ] I am able to understand all the help messages, if not, exchange with the PO or TW to rewrite them.
- [ ] After having created the PR, I will make sure that all the tests provided in this PR have run and passed.

View File

@ -111,7 +111,6 @@ runs:
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const warningNoPromote = 'No packages are promoted because push is not related to a hotfix/release pull request.';
const commitSha = context.sha;
const pulls = await github.rest.pulls.list({
@ -123,25 +122,31 @@ runs:
per_page: 100
});
const pr = pulls.data.find(p => p.merge_commit_sha === commitSha);
core.startGroup(`Checking pull request linked to commit ${commitSha}`);
const pr = pulls.data.find(p => {
console.log(`Checking pull request ${p.number}("${p.title}") with merge commit ${p.merge_commit_sha}`);
return p.merge_commit_sha === commitSha;
});
core.endGroup();
if (!pr) {
core.warning(warningNoPromote);
core.error(`No pull request found for merge commit ${commitSha}`);
return;
}
const prBaseRef = pr?.base?.ref || 'unknown';
const prHeadRef = pr?.head?.ref || 'unknown';
let releaseType = '';
switch (true) {
case /^release.+/.test(prBaseRef):
case /^release.+/.test(prHeadRef):
releaseType = 'release';
break;
case /^hotfix.+/.test(prBaseRef):
case /^hotfix.+/.test(prHeadRef):
releaseType = 'hotfix';
break;
default:
core.warning(warningNoPromote);
core.error(`No packages are promoted because push of branch ${prHeadRef} is not related to a hotfix/release pull request.`);
return;
}
console.log(`Release type: ${releaseType}`);
let fromStabilitySubdirectory = 'testing';
if (releaseType === 'hotfix' ) {
@ -154,11 +159,11 @@ runs:
);
} else if ('${{ steps.parse-distrib.outputs.distrib_family }}' === 'ubuntu') {
await exec.exec(
`jf rt download "ubuntu-plugins-testing/pool/${{ inputs.module_name }}/*${{ steps.parse-distrib.outputs.package_distrib_name }}*.deb" --props "release_type=${{ inputs.release_type }}" --flat`
`jf rt download "ubuntu-plugins-testing/pool/${{ inputs.module_name }}/*${{ steps.parse-distrib.outputs.package_distrib_name }}*.deb" --props "release_type=${releaseType}" --flat`
);
} else if ('${{ steps.parse-distrib.outputs.distrib_family }}' === 'debian') {
await exec.exec(
`jf rt download "apt-plugins-testing/pool/${{ inputs.module_name }}/*${{ steps.parse-distrib.outputs.package_distrib_name }}*.deb" --props "release_type=${{ inputs.release_type }}" --flat`
`jf rt download "apt-plugins-testing/pool/${{ inputs.module_name }}/*${{ steps.parse-distrib.outputs.package_distrib_name }}*.deb" --props "release_type=${releaseType}" --flat`
);
}

View File

@ -66,15 +66,21 @@ runs:
shell: bash
- name: Promote DEB package to stable
if: ${{ contains(fromJSON('["bullseye", "bookworm"]'), inputs.distrib) }}
if: ${{ contains(fromJSON('["bullseye", "bookworm", "jammy"]'), inputs.distrib) }}
run: |
set -eux
echo "[DEBUG] - Distrib: ${{ inputs.distrib }}"
echo "[DEBUG] - Distrib: ${{ inputs.module }}"
if [[ "${{ inputs.distrib }}" == "jammy" ]]; then
repo="ubuntu-plugins"
else
repo="apt-plugins"
fi
echo "[DEBUG] - Get path of testing DEB packages to promote to stable."
SRC_PATHS=$(jf rt search --include-dirs apt-plugins-testing/pool/${{ inputs.module }}/*${{ steps.parse-distrib.outputs.package_distrib_name }}*.deb | jq -r '.[].path')
SRC_PATHS=$(jf rt search --include-dirs $repo-testing/pool/${{ inputs.module }}/*${{ steps.parse-distrib.outputs.package_distrib_name }}*.deb | jq -r '.[].path')
if [[ ${SRC_PATHS[@]} ]]; then
for SRC_PATH in ${SRC_PATHS[@]}; do
@ -86,7 +92,7 @@ runs:
fi
echo "[DEBUG] - Build target path."
TARGET_PATH="apt-plugins-${{ inputs.stability }}/pool/${{ inputs.module }}/"
TARGET_PATH="$repo-${{ inputs.stability }}/pool/${{ inputs.module }}/"
echo "[DEBUG] - Target path: $TARGET_PATH"
echo "[DEBUG] - Promoting DEB testing artifacts to stable."

View File

@ -2,7 +2,7 @@ ARG REGISTRY_URL=docker.io
FROM ${REGISTRY_URL}/debian:bookworm
ENV DEBIAN_FRONTEND noninteractive
ENV DEBIAN_FRONTEND=noninteractive
# fix locale
RUN bash -e <<EOF
@ -15,9 +15,13 @@ apt-get clean
EOF
ENV LANG en_US.utf8
ENV LANG=en_US.utf8
RUN bash -e <<EOF
# Avoid apt to clean packages cache directory
rm -f /etc/apt/apt.conf.d/docker-clean
apt-get update
# Install Robotframework
apt-get install -y python3-dev python3-pip

View File

@ -2,7 +2,7 @@ ARG REGISTRY_URL=docker.io
FROM ${REGISTRY_URL}/debian:bullseye
ENV DEBIAN_FRONTEND noninteractive
ENV DEBIAN_FRONTEND=noninteractive
# fix locale
RUN bash -e <<EOF
@ -15,9 +15,13 @@ apt-get clean
EOF
ENV LANG en_US.utf8
ENV LANG=en_US.utf8
RUN bash -e <<EOF
# Avoid apt to clean packages cache directory
rm -f /etc/apt/apt.conf.d/docker-clean
apt-get update
# Install Robotframework
apt-get install -y python3 python3-dev python3-pip

View File

@ -2,7 +2,7 @@ ARG REGISTRY_URL=docker.io
FROM ${REGISTRY_URL}/ubuntu:jammy
ENV DEBIAN_FRONTEND noninteractive
ENV DEBIAN_FRONTEND=noninteractive
# fix locale
RUN bash -e <<EOF
@ -15,9 +15,13 @@ apt-get clean
EOF
ENV LANG en_US.utf8
ENV LANG=en_US.utf8
RUN bash -e <<EOF
# Avoid apt to clean packages cache directory
rm -f /etc/apt/apt.conf.d/docker-clean
apt-get update
# Install Robotframework
apt-get install -y python3 python3-dev python3-pip

View File

@ -1,23 +1,62 @@
use strict;
use warnings;
use Test::More;
use Test::Spelling;
use List::MoreUtils qw(uniq);
# the command must have at least one argument
if (!@ARGV) {
die "Usage: perl pod_spell_check.t module.pm stopwords.t";
}
# the first argument is the module to check
my $module_to_check = $ARGV[0];
# the second (optional) argument is the additional dictionary
my $stopword_filename='tests/resources/spellcheck/stopwords.txt';
if(defined($ARGV[1])){
$stopword_filename=$ARGV[1];
}
open(FILE, "<", $stopword_filename)
or die "Could not open $stopword_filename";
printf("Using dictionary: ".$stopword_filename." \n");
add_stopwords(<FILE>);
close(FILE);
set_spell_cmd('hunspell -l');
all_pod_files_spelling_ok($ARGV[0]);
# get_stopwords(): reads the text file and returns its content as an array or strings
sub get_stopwords {
my ($file) = @_;
open(FILE, "<", $stopword_filename)
or die "Could not open $stopword_filename";
printf("Using dictionary: ".$stopword_filename." \n");
my @stop_words;
for my $line (<FILE>) {
chomp $line;
push @stop_words, $line;
}
close(FILE);
return @stop_words;
}
# get_module_options(): reads the Perl module file's POD and returns all the encountered --options
sub get_module_options {
my ($module) = @_;
my @cmd_result = `perldoc -T $module_to_check`;
my @new_words;
for my $pod_line (@cmd_result) {
chomp $pod_line;
my @parsed_options = $pod_line =~ /(--[\w-]+){1,}\s?/mg or next;
push @new_words, @parsed_options;
}
return uniq(sort(@new_words));
}
my @known_words = get_stopwords($stopword_filename);
my @module_options = get_module_options($module_to_check);
# take all words from the text file and the module's options as valid words
add_stopwords(@known_words, @module_options);
# prepare the spelling check command
set_spell_cmd('hunspell -d en_US -l');
# check that all is correct in the Perl module file given as an argument
all_pod_files_spelling_ok($module_to_check);

View File

@ -74,8 +74,8 @@ def install_plugin(plugin, archi):
"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
elif archi == "rpm":
outfile.write("dnf install -y ./" + plugin + "*.rpm\n")
output_status = (subprocess.run("dnf install -y ./" + plugin + "*.rpm", shell=True, check=False,
outfile.write("dnf install --setopt=keepcache=True -y ./" + plugin + "*.rpm\n")
output_status = (subprocess.run("dnf install --setopt=keepcache=True -y ./" + plugin + "*.rpm", shell=True, check=False,
stderr=subprocess.STDOUT, stdout=outfile)).returncode
else:
print(f"Unknown architecture, expected deb or rpm, got {archi}. Exiting.")
@ -95,8 +95,8 @@ def remove_plugin(plugin, archi):
# 'autoremove', contrary to 'remove' all dependancy while removing the original package.
elif archi == "rpm":
outfile.write("dnf remove -y " + plugin + "\n")
output_status = (subprocess.run("dnf remove -y " + plugin, shell=True, check=False,
outfile.write("dnf remove --setopt=keepcache=True -y " + plugin + "\n")
output_status = (subprocess.run("dnf remove --setopt=keepcache=True -y " + plugin, shell=True, check=False,
stderr=subprocess.STDOUT, stdout=outfile)).returncode
else:
print(f"Unknown architecture, expected deb or rpm, got {archi}. Exiting.")

View File

@ -24,6 +24,9 @@ jobs:
package:
needs: [get-environment]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
runs-on: ubuntu-22.04
strategy:
fail-fast: false
@ -107,6 +110,7 @@ jobs:
deliver-packages:
needs: [get-environment, package]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
(contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) || ( needs.get-environment.outputs.stability == 'stable' && github.event_name != 'workflow_dispatch')) &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
@ -141,3 +145,12 @@ jobs:
stability: ${{ needs.get-environment.outputs.stability }}
release_type: ${{ needs.get-environment.outputs.release_type }}
artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
set-skip-label:
needs: [get-environment, deliver-packages]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/set-pull-request-skip-label.yml

View File

@ -26,7 +26,9 @@ jobs:
package:
needs: [get-environment]
if: ${{ needs.get-environment.outputs.stability != 'stable' }}
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
runs-on: ubuntu-22.04
strategy:
matrix:
@ -84,6 +86,7 @@ jobs:
deliver-packages:
needs: [get-environment, package]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
(contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) || ( needs.get-environment.outputs.stability == 'stable' && github.event_name != 'workflow_dispatch')) &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
@ -118,3 +121,12 @@ jobs:
stability: ${{ needs.get-environment.outputs.stability }}
release_type: ${{ needs.get-environment.outputs.release_type }}
artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
set-skip-label:
needs: [get-environment, deliver-packages]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/set-pull-request-skip-label.yml

View File

@ -18,7 +18,14 @@ on:
- ".github/docker/packaging/*"
jobs:
create-and-push-docker:
get-environment:
uses: ./.github/workflows/get-environment.yml
dockerize:
needs: [get-environment]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
strategy:
fail-fast: false
matrix:
@ -87,3 +94,12 @@ jobs:
pull: true
push: true
tags: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/${{ matrix.image }}:latest
set-skip-label:
needs: [get-environment, dockerize]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/set-pull-request-skip-label.yml

View File

@ -18,27 +18,34 @@ on:
- ".github/docker/testing/*"
jobs:
create-and-push-docker:
get-environment:
uses: ./.github/workflows/get-environment.yml
dockerize:
needs: [get-environment]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
strategy:
fail-fast: false
matrix:
include:
- runner: ubuntu-22.04
- runner: ubuntu-24.04
dockerfile: alma8
image: alma8
- runner: ubuntu-22.04
- runner: ubuntu-24.04
dockerfile: alma9
image: alma9
- runner: ubuntu-22.04
- runner: ubuntu-24.04
dockerfile: bullseye
image: bullseye
- runner: ["self-hosted", "collect-arm64"]
dockerfile: bullseye
image: bullseye-arm64
- runner: ubuntu-22.04
- runner: ubuntu-24.04
dockerfile: bookworm
image: bookworm
- runner: ubuntu-22.04
- runner: ubuntu-24.04
dockerfile: jammy
image: jammy
@ -72,3 +79,12 @@ jobs:
pull: true
push: true
tags: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/testing-plugins-${{ matrix.image }}:latest
set-skip-label:
needs: [get-environment, dockerize]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/set-pull-request-skip-label.yml

View File

@ -18,7 +18,14 @@ on:
- ".github/docker/unit-tests/*"
jobs:
create-and-push-docker:
get-environment:
uses: ./.github/workflows/get-environment.yml
dockerize:
needs: [get-environment]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
strategy:
fail-fast: false
matrix:
@ -72,3 +79,12 @@ jobs:
pull: true
push: true
tags: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/unit-tests-${{ matrix.image }}:latest
set-skip-label:
needs: [get-environment, dockerize]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/set-pull-request-skip-label.yml

View File

@ -23,6 +23,9 @@ on:
is_targeting_feature_branch:
description: "if it is a PR, check if targeting a feature branch"
value: ${{ jobs.get-environment.outputs.is_targeting_feature_branch }}
skip_workflow:
description: "if the current workflow should be skipped"
value: ${{ jobs.get-environment.outputs.skip_workflow }}
jobs:
get-environment:
@ -34,10 +37,128 @@ jobs:
target_stability: ${{ steps.get_stability.outputs.target_stability }}
release_type: ${{ steps.get_release_type.outputs.release_type }}
is_targeting_feature_branch: ${{ steps.get_stability.outputs.is_targeting_feature_branch }}
skip_workflow: ${{ steps.skip_workflow.outputs.result }}
steps:
- name: Check if PR has skip label
id: has_skip_label
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
let hasSkipLabel = false;
if (${{ contains(fromJSON('["pull_request", "pull_request_target"]') , github.event_name) }} === true) {
try {
const labels = await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number
});
labels.data.forEach(({ name }) => {
if (name === '${{ format('skip-workflow-{0}', github.workflow) }}') {
hasSkipLabel = true;
}
});
} catch (e) {
core.warning(`failed to list labels: ${e}`);
}
}
return hasSkipLabel;
- name: Checkout sources (current branch)
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
with:
fetch-depth: ${{ steps.has_skip_label.outputs.result == 'true' && 100 || 1 }}
- if: ${{ steps.has_skip_label.outputs.result == 'true' }}
name: Get workflow triggered paths
id: get_workflow_triggered_paths
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const fs = require('fs');
let paths = [];
const workflowFilePath = '${{ github.workflow_ref }}'.replace('${{ github.repository }}/', '').split('@').shift();
if (fs.existsSync(workflowFilePath)) {
const workflowFileContent = fs.readFileSync(workflowFilePath, 'utf8');
const workflowFileContentLines = workflowFileContent.split('\n');
let hasReadOn = false;
let hasReadPullRequest = false;
let hasReadPaths = false;
for (const line of workflowFileContentLines) {
if (line.match(/^on:\s*$/)) {
hasReadOn = true;
continue;
}
if (line.match(/^\s{2}pull_request(_target)?:\s*$/)) {
hasReadPullRequest = true;
continue;
}
if (line.match(/^\s{4}paths:\s*$/)) {
hasReadPaths = true;
continue;
}
if (hasReadOn && hasReadPullRequest && hasReadPaths) {
const matches = line.match(/^\s{6}-\s['"](.+)['"]\s*$/);
if (matches) {
paths.push(matches[1].trim());
} else {
break;
}
}
}
}
if (paths.length === 0) {
paths = ['**'];
}
console.log(paths);
return paths;
- if: ${{ steps.has_skip_label.outputs.result == 'true' }}
name: Get push changes
id: get_push_changes
uses: tj-actions/changed-files@bab30c2299617f6615ec02a68b9a40d10bd21366 # v45.0.5
with:
since_last_remote_commit: true
json: true
escape_json: false
files: ${{ join(fromJSON(steps.get_workflow_triggered_paths.outputs.result), ';') }}
files_separator: ';'
- name: Check if current workflow should be skipped
id: skip_workflow
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
if (${{ steps.has_skip_label.outputs.result }} === false) {
return false;
}
const label = '${{ format('skip-workflow-{0}', github.workflow) }}';
if ('${{ steps.get_push_changes.outputs.any_changed }}' === 'true') {
try {
await github.rest.issues.removeLabel({
name: label,
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number
});
core.notice(`label ${label} removed because changes were detected on last push.`);
} catch (e) {
core.warning(`failed to remove label ${label}: ${e}`);
}
return false;
}
return true;
- if: ${{ github.event_name == 'pull_request' }}
name: Get nested pull request path
@ -155,6 +276,7 @@ jobs:
['release_type', '${{ steps.get_release_type.outputs.release_type || '<em>not defined because this is not a release</em>' }}'],
['is_targeting_feature_branch', '${{ steps.get_stability.outputs.is_targeting_feature_branch }}'],
['target_stability', '${{ steps.get_stability.outputs.target_stability || '<em>not defined because current run is not triggered by pull request event</em>' }}'],
['skip_workflow', '${{ steps.skip_workflow.outputs.result }}']
];
core.summary
.addHeading(`${context.workflow} environment outputs`)

View File

@ -24,6 +24,9 @@ jobs:
package:
needs: [get-environment]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
runs-on: ubuntu-24.04
strategy:
fail-fast: false
@ -117,6 +120,7 @@ jobs:
deliver-packages:
needs: [get-environment, package]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
(contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) || ( needs.get-environment.outputs.stability == 'stable' && github.event_name != 'workflow_dispatch')) &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
@ -151,3 +155,12 @@ jobs:
stability: ${{ needs.get-environment.outputs.stability }}
release_type: ${{ needs.get-environment.outputs.release_type }}
artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
set-skip-label:
needs: [get-environment, deliver-packages]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/set-pull-request-skip-label.yml

View File

@ -24,7 +24,9 @@ jobs:
package-rpm:
needs: [get-environment]
if: ${{ needs.get-environment.outputs.stability != 'stable' }}
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
runs-on: ubuntu-24.04
strategy:
@ -238,7 +240,10 @@ jobs:
retention-days: 1
merge-package-rpm-artifacts:
needs: [package-rpm]
needs: [get-environment, package-rpm]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
runs-on: ubuntu-24.04
strategy:
matrix:
@ -260,7 +265,10 @@ jobs:
failOnError: false
sign-rpm:
needs: [merge-package-rpm-artifacts]
needs: [get-environment, merge-package-rpm-artifacts]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
runs-on: ubuntu-24.04
strategy:
@ -298,7 +306,9 @@ jobs:
package-deb:
needs: [get-environment]
if: ${{ needs.get-environment.outputs.stability != 'stable' }}
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
runs-on: ${{ matrix.runner_name }}
strategy:
@ -316,6 +326,8 @@ jobs:
"DataStruct::Flat",
"DateTime::Format::Duration::ISO8601",
"Device::Modbus",
"Device::Modbus::RTU::Client",
"Device::Modbus::TCP::Client",
"Digest::SHA1",
"Email::Send::SMTP::Gmail",
"Hash::Ordered",
@ -356,6 +368,10 @@ jobs:
image: packaging-plugins-bullseye-arm64
arch: arm64
runner_name: ["self-hosted", "collect-arm64"]
- name: "Device::Modbus::RTU::Client"
build_distribs: "bookworm"
- name: "Device::Modbus::TCP::Client"
build_distribs: "bookworm"
- name: "Net::Amazon::Signature::V4"
build_distribs: ["bullseye", "jammy"]
- name: "Net::MQTT::Simple"
@ -464,7 +480,10 @@ jobs:
retention-days: 1
merge-package-deb-artifacts:
needs: [package-deb]
needs: [get-environment, package-deb]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
runs-on: ubuntu-24.04
strategy:
matrix:
@ -486,7 +505,10 @@ jobs:
failOnError: false
download-and-cache-deb:
needs: [merge-package-deb-artifacts]
needs: [get-environment, merge-package-deb-artifacts]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
runs-on: ubuntu-24.04
strategy:
matrix:
@ -505,6 +527,7 @@ jobs:
deliver-packages:
needs: [get-environment, sign-rpm, download-and-cache-deb]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
(contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) || ( needs.get-environment.outputs.stability == 'stable' && github.event_name != 'workflow_dispatch')) &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
@ -539,3 +562,12 @@ jobs:
stability: ${{ needs.get-environment.outputs.stability }}
release_type: ${{ needs.get-environment.outputs.release_type }}
artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
set-skip-label:
needs: [get-environment, deliver-packages]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/set-pull-request-skip-label.yml

View File

@ -26,7 +26,9 @@ jobs:
package:
needs: [get-environment]
if: ${{ needs.get-environment.outputs.stability != 'stable' }}
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
strategy:
fail-fast: false
@ -144,6 +146,7 @@ jobs:
deliver-packages:
needs: [get-environment, package]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
(contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) || ( needs.get-environment.outputs.stability == 'stable' && github.event_name != 'workflow_dispatch')) &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
@ -187,3 +190,12 @@ jobs:
stability: ${{ needs.get-environment.outputs.stability }}
release_type: ${{ needs.get-environment.outputs.release_type }}
artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
set-skip-label:
needs: [get-environment, deliver-packages]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/set-pull-request-skip-label.yml

View File

@ -24,7 +24,9 @@ jobs:
package-rpm:
needs: [get-environment]
if: ${{ needs.get-environment.outputs.stability != 'stable' }}
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
runs-on: ubuntu-22.04
strategy:
@ -67,7 +69,10 @@ jobs:
key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
sign-rpm:
needs: [package-rpm]
needs: [get-environment, package-rpm]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
runs-on: ubuntu-22.04
strategy:
matrix:
@ -110,7 +115,9 @@ jobs:
package-deb:
needs: [get-environment]
if: ${{ needs.get-environment.outputs.stability != 'stable' }}
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
runs-on: ubuntu-22.04
strategy:
@ -156,6 +163,7 @@ jobs:
deliver-packages:
needs: [get-environment, sign-rpm, package-deb]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
(contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) || ( needs.get-environment.outputs.stability == 'stable' && github.event_name != 'workflow_dispatch')) &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
@ -190,3 +198,12 @@ jobs:
stability: ${{ needs.get-environment.outputs.stability }}
release_type: ${{ needs.get-environment.outputs.release_type }}
artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
set-skip-label:
needs: [get-environment, deliver-packages]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/set-pull-request-skip-label.yml

View File

@ -26,7 +26,9 @@ jobs:
package:
needs: [get-environment]
if: ${{ needs.get-environment.outputs.stability != 'stable' }}
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
strategy:
fail-fast: false
@ -129,6 +131,7 @@ jobs:
deliver-packages:
needs: [get-environment, package]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
(contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) || ( needs.get-environment.outputs.stability == 'stable' && github.event_name != 'workflow_dispatch')) &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
@ -163,3 +166,12 @@ jobs:
stability: ${{ needs.get-environment.outputs.stability }}
release_type: ${{ needs.get-environment.outputs.release_type }}
artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
set-skip-label:
needs: [get-environment, deliver-packages]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/set-pull-request-skip-label.yml

View File

@ -27,6 +27,9 @@ jobs:
package:
needs: [get-environment]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
strategy:
fail-fast: false
@ -154,3 +157,12 @@ jobs:
stability: ${{ needs.get-environment.outputs.stability }}
release_type: ${{ needs.get-environment.outputs.release_type }}
artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
set-skip-label:
needs: [get-environment, deliver-packages]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/set-pull-request-skip-label.yml

View File

@ -24,7 +24,9 @@ jobs:
package:
needs: [get-environment]
if: ${{ needs.get-environment.outputs.stability != 'stable' }}
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
strategy:
fail-fast: false
@ -142,6 +144,7 @@ jobs:
deliver-packages:
needs: [get-environment, package]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
(contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) || ( needs.get-environment.outputs.stability == 'stable' && github.event_name != 'workflow_dispatch')) &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
@ -185,3 +188,12 @@ jobs:
stability: ${{ needs.get-environment.outputs.stability }}
release_type: ${{ needs.get-environment.outputs.release_type }}
artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
set-skip-label:
needs: [get-environment, deliver-packages]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/set-pull-request-skip-label.yml

View File

@ -24,7 +24,9 @@ jobs:
package:
needs: [get-environment]
if: ${{ needs.get-environment.outputs.stability != 'stable' }}
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
strategy:
fail-fast: false
@ -142,6 +144,7 @@ jobs:
deliver-packages:
needs: [get-environment, package]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
(contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) || ( needs.get-environment.outputs.stability == 'stable' && github.event_name != 'workflow_dispatch')) &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
@ -185,3 +188,12 @@ jobs:
stability: ${{ needs.get-environment.outputs.stability }}
release_type: ${{ needs.get-environment.outputs.release_type }}
artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
set-skip-label:
needs: [get-environment, deliver-packages]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/set-pull-request-skip-label.yml

View File

@ -22,7 +22,9 @@ jobs:
package:
needs: [get-environment]
if: ${{ needs.get-environment.outputs.stability != 'stable' }}
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
strategy:
fail-fast: false
@ -214,6 +216,7 @@ jobs:
deliver-packages:
needs: [get-environment, package]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
(contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) || ( needs.get-environment.outputs.stability == 'stable' && github.event_name != 'workflow_dispatch')) &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
@ -257,3 +260,12 @@ jobs:
stability: ${{ needs.get-environment.outputs.stability }}
release_type: ${{ needs.get-environment.outputs.release_type }}
artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
set-skip-label:
needs: [get-environment, deliver-packages]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/set-pull-request-skip-label.yml

View File

@ -24,7 +24,9 @@ jobs:
get-sources:
needs: [get-environment]
if: ${{ needs.get-environment.outputs.stability != 'stable' }}
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
runs-on: ubuntu-22.04
steps:
- name: Download vsphere cli sources
@ -48,6 +50,9 @@ jobs:
package:
needs: [get-environment, get-sources]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
strategy:
matrix:
@ -148,6 +153,7 @@ jobs:
deliver-packages:
needs: [get-environment, package]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
(contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) || ( needs.get-environment.outputs.stability == 'stable' && github.event_name != 'workflow_dispatch')) &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
@ -191,3 +197,12 @@ jobs:
stability: ${{ needs.get-environment.outputs.stability }}
release_type: ${{ needs.get-environment.outputs.release_type }}
artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
set-skip-label:
needs: [get-environment, deliver-packages]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/set-pull-request-skip-label.yml

View File

@ -24,7 +24,9 @@ jobs:
package-rpm:
needs: [get-environment]
if: ${{ needs.get-environment.outputs.stability != 'stable' }}
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
runs-on: ubuntu-22.04
strategy:
matrix:
@ -61,7 +63,10 @@ jobs:
key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
sign-rpm:
needs: [package-rpm]
needs: [get-environment, package-rpm]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
runs-on: ubuntu-22.04
strategy:
matrix:
@ -111,6 +116,7 @@ jobs:
deliver-packages:
needs: [get-environment, sign-rpm]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
(contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) || ( needs.get-environment.outputs.stability == 'stable' && github.event_name != 'workflow_dispatch')) &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
@ -139,3 +145,12 @@ jobs:
stability: ${{ needs.get-environment.outputs.stability }}
release_type: ${{ needs.get-environment.outputs.release_type }}
artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
set-skip-label:
needs: [get-environment, deliver-packages]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/set-pull-request-skip-label.yml

View File

@ -24,6 +24,9 @@ jobs:
package:
needs: [get-environment]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable'
runs-on: ubuntu-22.04
strategy:
matrix:
@ -72,6 +75,7 @@ jobs:
deliver-packages:
needs: [get-environment, package]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
(contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) || ( needs.get-environment.outputs.stability == 'stable' && github.event_name != 'workflow_dispatch')) &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
@ -100,3 +104,12 @@ jobs:
stability: ${{ needs.get-environment.outputs.stability }}
release_type: ${{ needs.get-environment.outputs.release_type }}
artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
set-skip-label:
needs: [get-environment, deliver-packages]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/set-pull-request-skip-label.yml

View File

@ -29,11 +29,11 @@ jobs:
uses: ./.github/workflows/get-environment.yml
get-plugins:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
outputs:
plugins: ${{ steps.get_plugins.outputs.plugins }}
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
@ -89,12 +89,18 @@ jobs:
unit-tests:
needs: [get-environment, get-plugins]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-environment.outputs.stability != 'stable' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
strategy:
fail-fast: false
matrix:
image: [unit-tests-alma8, unit-tests-alma9, unit-tests-bullseye, unit-tests-bullseye-arm64, unit-tests-bookworm, unit-tests-jammy]
include:
- runner_name: ubuntu-22.04
- runner_name: ubuntu-24.04
- package_extension: rpm
image: unit-tests-alma8
distrib: el8
@ -121,9 +127,10 @@ jobs:
credentials:
username: ${{ secrets.HARBOR_CENTREON_PULL_USERNAME }}
password: ${{ secrets.HARBOR_CENTREON_PULL_TOKEN }}
steps:
- name: Checkout sources
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Run unit tests
uses: ./.github/actions/unit-tests
@ -137,14 +144,17 @@ jobs:
retention-days: 1
fatpacker:
if: ${{ needs.get-plugins.outputs.plugins != '' }}
needs: [get-environment, get-plugins, unit-tests]
runs-on: ubuntu-22.04
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-plugins.outputs.plugins != '' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
runs-on: ubuntu-24.04
steps:
- name: Checkout sources
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
fetch-depth: 1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Prepare FatPacker
uses: shogo82148/actions-setup-perl@9c1eca9952ccc07f9ca4a2097b63df93d9d138e9 # v1.31.3
@ -166,6 +176,13 @@ jobs:
package:
runs-on: ubuntu-24.04
needs: [get-environment, get-plugins, fatpacker]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-plugins.outputs.plugins != '' &&
needs.get-environment.outputs.stability != 'stable' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
strategy:
fail-fast: false
@ -200,7 +217,7 @@ jobs:
steps:
- name: Checkout sources
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
with:
@ -284,6 +301,13 @@ jobs:
test-plugins:
needs: [get-environment, get-plugins, package]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-plugins.outputs.plugins != '' &&
needs.get-environment.outputs.stability != 'stable' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
strategy:
fail-fast: false
matrix:
@ -319,7 +343,7 @@ jobs:
password: ${{ secrets.HARBOR_CENTREON_PULL_TOKEN }}
steps:
- name: Checkout sources
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./.github/actions/test-plugins
with:
@ -338,8 +362,9 @@ jobs:
deliver-packages:
needs: [get-environment, get-plugins, test-plugins]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
needs.get-plugins.outputs.plugins != '' &&
(contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) || ( needs.get-environment.outputs.stability == 'stable' && github.event_name != 'workflow_dispatch')) &&
(contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) || (needs.get-environment.outputs.stability == 'stable' && github.event_name != 'workflow_dispatch')) &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
@ -364,7 +389,7 @@ jobs:
name: deliver ${{ matrix.distrib }}
steps:
- name: Checkout sources
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Delivery
uses: ./.github/actions/package-delivery
@ -377,13 +402,15 @@ jobs:
artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
deliver-sources:
needs: [get-environment]
if: ${{ needs.get-environment.outputs.stability == 'stable' && github.event_name == 'push' }}
needs: [get-environment, fatpacker]
if: |
needs.get-environment.outputs.stability == 'stable' &&
github.event_name == 'push'
runs-on: [self-hosted, common]
steps:
- name: Checkout sources
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
with:
@ -408,7 +435,7 @@ jobs:
steps:
- name: Checkout sources
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Push git release tag
run: |
@ -426,3 +453,12 @@ jobs:
echo "::warning::Release tag $RELEASE already exists"
fi
shell: bash
set-skip-label:
needs: [get-environment, deliver-packages]
if: |
needs.get-environment.outputs.skip_workflow == 'false' &&
! cancelled() &&
! contains(needs.*.result, 'failure') &&
! contains(needs.*.result, 'cancelled')
uses: ./.github/workflows/set-pull-request-skip-label.yml

View File

@ -0,0 +1,32 @@
name: set-pull-request-external-label
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
on:
pull_request_target:
jobs:
set-pull-request-external-label:
if: |
github.event.pull_request.head.repo.fork &&
! contains(github.event.pull_request.labels.*.name, 'external')
runs-on: ubuntu-24.04
steps:
- name: Set PR external label
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const label = 'external';
try {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
labels: [label]
});
} catch (e) {
core.warning(`failed to add label ${label}: ${e}`);
}

View File

@ -0,0 +1,26 @@
name: set-pull-request-skip-label
on:
workflow_call:
jobs:
set-pull-request-skip-label:
if: ${{ success() && contains(fromJSON('["pull_request", "pull_request_target"]') , github.event_name) }}
runs-on: ubuntu-24.04
steps:
- name: Set PR skip label
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const label = '${{ format('skip-workflow-{0}', github.workflow) }}';
try {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
labels: [label]
});
} catch (e) {
core.warning(`failed to add label ${label}: ${e}`);
}

View File

@ -15,7 +15,7 @@ on:
jobs:
pod-spell-check:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'do-not-spellcheck') }}
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
@ -34,7 +34,7 @@ jobs:
with:
perl-version: '5.34'
install-modules-with: cpm
install-modules: Test::More Test::Spelling
install-modules: Test::More Test::Spelling List::MoreUtils
- name: Install librairies
continue-on-error: true

View File

@ -30,10 +30,7 @@ on_centreon_rtd = os.environ.get('CENTREON_RTD', None) == 'True'
extensions = ['sphinx.ext.todo', 'sphinx.ext.intersphinx']
intersphinx_mapping = {
'centreon-engine': ('http://documentation.centreon.com/docs/centreon-engine/en/latest', None),
'centreon-broker': ('http://documentation.centreon.com/docs/centreon-broker/en/latest', None),
'centreon-clib': ('http://documentation.centreon.com/docs/centreon-clib/en/latest', None),
'ces': ('http://documentation.centreon.com/docs/centreon-enterprise-server/en/latest', None),
'centreon-documentation': ('https://docs.centreon.com/', None),
}
# Add any paths that contain templates here, relative to this directory.

View File

@ -5,6 +5,7 @@
"files": [
"centreon/plugins/script_snmp.pm",
"centreon/plugins/snmp.pm",
"snmp_standard/mode/uptime.pm",
"storage/netapp/ontap/snmp/"
]
}

View File

@ -3,12 +3,13 @@
"pkg_summary": "Centreon Plugin",
"plugin_name": "centreon_huawei_snmp.pl",
"files": [
"centreon/common/huawei/standard/snmp",
"centreon/plugins/script_snmp.pm",
"centreon/plugins/snmp.pm",
"snmp_standard/mode/interfaces.pm",
"snmp_standard/mode/listinterfaces.pm",
"snmp_standard/mode/resources/",
"snmp_standard/mode/resources/",
"snmp_standard/mode/uptime.pm",
"network/huawei/snmp/"
"network/huawei/standard/snmp/"
]
}

View File

@ -0,0 +1,5 @@
{
"dependencies": [
"libsnmp-perl"
]
}

View File

@ -0,0 +1,15 @@
{
"pkg_name": "centreon-plugin-Network-Huawei-Wlc-Snmp",
"pkg_summary": "Centreon Plugin for Huawei WLC using SNMP protocol",
"plugin_name": "centreon_huawei_wlc_snmp.pl",
"files": [
"centreon/common/huawei/standard/snmp/",
"centreon/plugins/script_snmp.pm",
"centreon/plugins/snmp.pm",
"snmp_standard/mode/interfaces.pm",
"snmp_standard/mode/listinterfaces.pm",
"snmp_standard/mode/resources/",
"snmp_standard/mode/uptime.pm",
"network/huawei/wlc/snmp/"
]
}

View File

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

View File

@ -7,7 +7,10 @@
"centreon/plugins/snmp.pm",
"snmp_standard/mode/interfaces.pm",
"snmp_standard/mode/listinterfaces.pm",
"snmp_standard/mode/resources/",
"snmp_standard/mode/listspanningtrees.pm",
"snmp_standard/mode/resources/",
"snmp_standard/mode/spanningtree.pm",
"snmp_standard/mode/uptime.pm",
"network/hp/procurve/"
]
}

View File

@ -1,6 +1,7 @@
{
"dependencies": [
"libsnmp-perl",
"libdatetime-perl"
"libdatetime-perl",
"libnet-ntp-perl"
]
}

View File

@ -14,14 +14,15 @@
"snmp_standard/mode/loadaverage.pm",
"snmp_standard/mode/listdiskspath.pm",
"snmp_standard/mode/listinterfaces.pm",
"snmp_standard/mode/resources/",
"snmp_standard/mode/listprocesses.pm",
"snmp_standard/mode/resources/",
"snmp_standard/mode/listprocesses.pm",
"snmp_standard/mode/liststorages.pm",
"snmp_standard/mode/processcount.pm",
"snmp_standard/mode/storage.pm",
"snmp_standard/mode/swap.pm",
"snmp_standard/mode/tcpcon.pm",
"snmp_standard/mode/uptime.pm",
"snmp_standard/mode/ntp.pm",
"os/freebsd/snmp/"
]
}

View File

@ -1,6 +1,7 @@
{
"dependencies": [
"perl(SNMP)",
"perl(DateTime)"
"perl(DateTime)",
"perl(Net::NTP)"
]
}

View File

@ -43,14 +43,19 @@ sub new {
if (!defined($options{noptions})) {
$options{options}->add_options(arguments => {
'api-username:s' => { name => 'api_username' },
'api-password:s' => { name => 'api_password' },
'hostname:s' => { name => 'hostname' },
'port:s' => { name => 'port' },
'proto:s' => { name => 'proto' },
'timeout:s' => { name => 'timeout' },
'url-path:s' => { name => 'url_path' },
'authent-endpoint' => { name => 'authent_endpoint' }
'api-username:s' => { name => 'api_username' },
'api-password:s' => { name => 'api_password' },
'hostname:s' => { name => 'hostname' },
'port:s' => { name => 'port' },
'proto:s' => { name => 'proto' },
'timeout:s' => { name => 'timeout' },
'url-path:s' => { name => 'url_path' },
'filter-id:s' => { name => 'filter_id' },
'filter-name:s' => { name => 'filter_name' },
'filter-workspaceid:s' => { name => 'filter_workspaceid' },
'filter-siteid:s' => { name => 'filter_siteid' },
'filter-status:s@' => { name => 'filter_status' },
'authent-endpoint' => { name => 'authent_endpoint' }
});
}
$options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1);
@ -170,6 +175,57 @@ sub get_access_token {
return $access_token;
}
sub request_scenarios_status{
my ($self, %options) = @_;
my $status_filter = {};
my @get_param;
if (defined($self->{option_results}->{filter_status}) && $self->{option_results}->{filter_status}[0] ne '') {
$status_filter->{statusFilter} = $self->{option_results}->{filter_status};
}
if (defined($self->{option_results}->{filter_workspaceid}) && $self->{option_results}->{filter_workspaceid} ne '') {
push(@get_param, "workspaceId=$self->{option_results}->{filter_workspaceid}");
}
if (defined($self->{option_results}->{filter_siteid}) && $self->{option_results}->{filter_siteid} ne '') {
push(@get_param, "siteId=$self->{option_results}->{filter_siteid}");
}
my $results = $self->request_api(
endpoint => '/results-api/scenarios/status',
method => 'POST',
post_body => $status_filter,
get_param => \@get_param,
);
if (ref($results) eq "HASH" ) {
if (defined($results->{message})) {
$self->{output}->add_option_msg(short_msg => "Cannot get scenarios : " . $results->{message});
$self->{output}->option_exit();
}
if (defined($results->{error})) {
$self->{output}->add_option_msg(short_msg => "Cannot get scenarios : " . $results->{error});
$self->{output}->option_exit();
}
$self->{output}->add_option_msg(short_msg => "Cannot get scenarios due to an unknown error, please use the --debug option to find more information");
$self->{output}->option_exit();
}
my @scenarios;
for my $scenario (@$results) {
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$scenario->{scenarioName} !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(long_msg => "skipping scenario '" . $scenario->{scenarioName} . "': no matching filter.", debug => 1);
next;
}
if (defined($self->{option_results}->{filter_id}) && $self->{option_results}->{filter_id} ne '' &&
$scenario->{scenarioId} !~ /$self->{option_results}->{filter_id}/) {
$self->{output}->output_add(long_msg => "skipping scenario '" . $scenario->{scenarioName} . "': no matching filter.", debug => 1);
next;
}
push(@scenarios, $scenario);
}
return \@scenarios;
}
sub request_api {
my ($self, %options) = @_;
@ -195,7 +251,7 @@ sub request_api {
$json = JSON::XS->new->utf8->decode($response);
};
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot decode Vault JSON response: $@");
$self->{output}->add_option_msg(short_msg => "Cannot decode ekara JSON response: $@");
$self->{output}->option_exit();
};
@ -209,11 +265,11 @@ __END__
=head1 NAME
Ip-Label Ekara Rest API
ip-label Ekara Rest API
=head1 REST API OPTIONS
Ip-Label Ekara Rest API
ip-label Ekara Rest API
=over 8
@ -237,6 +293,37 @@ Set username.
Set password.
=item B<--filter-id>
Filter by monitor ID (can be a regexp).
=item B<--filter-name>
Filter by monitor name (can be a regexp).
=item B<--filter-status>
Filter by numeric status (can be multiple).
0 => 'Unknown',
1 => 'Success',
2 => 'Failure',
3 => 'Aborted',
4 => 'No execution',
5 => 'No execution',
6 => 'Stopped',
7 => 'Excluded',
8 => 'Degraded'
Example: --filter-status='1,2'
=item B<--filter-workspaceid>
Filter scenario to check by workspace id.
=item B<--filter-siteid>
Filter scenario to check by site id.
=item B<--timeout>
Set timeout in seconds (default: 10).

View File

@ -36,6 +36,7 @@ sub custom_status_output {
sub custom_duration_output {
my ($self, %options) = @_;
if ($self->{result_values}->{status} =~ 'Open') {
return sprintf(
'start time: %s, duration: %s',
@ -145,8 +146,6 @@ sub new {
bless $self, $class;
$options{options}->add_options(arguments => {
'filter-id:s' => { name => 'filter_id' },
'filter-name:s' => { name => 'filter_name' },
'ignore-closed' => { name => 'ignore_closed' },
'timeframe:s' => { name => 'timeframe'}
});
@ -176,23 +175,10 @@ my $status_mapping = {
sub manage_selection {
my ($self, %options) = @_;
my $results = $options{custom}->request_api(
endpoint => '/results-api/scenarios/status',
method => 'POST',
);
my $results = $options{custom}->request_scenarios_status();
my $scenarios_list = {};
foreach (@$results) {
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$_->{scenarioName} !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(long_msg => "skipping scenario '" . $_->{scenarioName} . "': no matching filter.", debug => 1);
next;
}
if (defined($self->{option_results}->{filter_id}) && $self->{option_results}->{filter_id} ne '' &&
$_->{scenarioId} !~ /$self->{option_results}->{filter_id}/) {
$self->{output}->output_add(long_msg => "skipping scenario '" . $_->{scenarioName} . "': no matching filter.", debug => 1);
next;
}
push @{$scenarios_list->{scenarioIds}}, $_->{scenarioId};
}
@ -212,6 +198,10 @@ sub manage_selection {
);
}
else{
$self->{output}->add_option_msg(short_msg => "No scenarios found, can't search for incidents. Please check filters.");
$self->{output}->option_exit();
}
$self->{global}->{total} = 0;
@ -257,7 +247,7 @@ __END__
=head1 MODE
Check IP Label Ekara incidents.
Check Ekara incidents.
=over 8
@ -266,14 +256,6 @@ Check IP Label Ekara incidents.
Set timeframe period in seconds. (default: 900)
Example: --timeframe='3600' will check the last hour
=item B<--filter-id>
Filter by monitor ID (can be a regexp).
=item B<--filter-name>
Filter by monitor name (can be a regexp).
=item B<--ignore-closed>
Ignore solved incidents within the timeframe.

View File

@ -34,16 +34,6 @@ sub custom_status_output {
return sprintf('status: %s (%s)', $self->{result_values}->{status}, $self->{result_values}->{num_status});
}
sub custom_date_output {
my ($self, %options) = @_;
return sprintf(
'last execution: %s (%s ago)',
$self->{result_values}->{lastexec},
centreon::plugins::misc::change_seconds(value => $self->{result_values}->{freshness})
);
}
sub prefix_scenario_output {
my ($self, %options) = @_;
@ -131,9 +121,7 @@ sub new {
bless $self, $class;
$options{options}->add_options(arguments => {
'filter-id:s' => { name => 'filter_id' },
'filter-name:s' => { name => 'filter_name' },
'filter-status:s@' => { name => 'filter_status' },
'filter-type:s' => { name => 'filter_type' },
'timeframe:s' => { name => 'timeframe'}
});
@ -162,35 +150,14 @@ my $status_mapping = {
sub manage_selection {
my ($self, %options) = @_;
my $status_filter = {};
if (defined($self->{option_results}->{filter_status}) && $self->{option_results}->{filter_status}[0] ne '') {
$status_filter->{statusFilter} = $self->{option_results}->{filter_status};
}
my $results = $options{custom}->request_api(
endpoint => '/results-api/scenarios/status',
method => 'POST',
post_body => $status_filter
);
my $results = $options{custom}->request_scenarios_status();
my $time = time();
my $start_date = POSIX::strftime('%Y-%m-%dT%H:%M:%SZ', gmtime($time - $self->{timeframe}));
my $end_date = POSIX::strftime('%Y-%m-%dT%H:%M:%SZ', gmtime($time));
foreach (@$results) {
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$_->{scenarioName} !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(long_msg => "skipping scenario '" . $_->{scenarioName} . "': no matching filter.", debug => 1);
next;
}
if (defined($self->{option_results}->{filter_id}) && $self->{option_results}->{filter_id} ne '' &&
$_->{scenarioId} !~ /$self->{option_results}->{filter_id}/) {
$self->{output}->output_add(long_msg => "skipping scenario '" . $_->{scenarioName} . "': no matching filter.", debug => 1);
next;
}
foreach my $scenario (@$results) {
my $scenario_detail = $options{custom}->request_api(
endpoint => '/results-api/results/' . $_->{scenarioId},
endpoint => '/results-api/results/' . $scenario->{scenarioId},
method => 'POST',
get_param => [
'from=' . $start_date,
@ -200,35 +167,38 @@ sub manage_selection {
if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '' &&
$scenario_detail->{infos}->{plugin_id} !~ /$self->{option_results}->{filter_type}/i) {
$self->{output}->output_add(long_msg => "skipping scenario '" . $_->{scenarioName} . "': no matching filter.", debug => 1);
$self->{output}->output_add(long_msg => "skipping scenario '" . $scenario->{scenarioName} . "': no matching filter.", debug => 1);
next;
}
$self->{scenarios}->{ $_->{scenarioName} } = {
display => $_->{scenarioName},
$self->{scenarios}->{ $scenario->{scenarioName} } = {
display => $scenario->{scenarioName},
global => {
display => $_->{scenarioName},
id => $_->{scenarioId},
num_status => $_->{currentStatus},
status => $status_mapping->{$_->{currentStatus}},
display => $scenario->{scenarioName},
id => $scenario->{scenarioId},
num_status => $scenario->{currentStatus},
status => $status_mapping->{$scenario->{currentStatus}} // 'Unknown',
}
};
foreach my $kpi (@{$scenario_detail->{kpis}}) {
$self->{scenarios}->{ $_->{scenarioName} }->{global}->{$kpi->{label}} = $kpi->{value};
if (!defined $scenario_detail->{results} or scalar(@{$scenario_detail->{results}}) <= 0) {
$self->{output}->add_option_msg(short_msg => "Scenario '" . $scenario->{scenarioName} . "' Don't have any performance data, please try to add a bigger timeframe");
next;
}
$self->{scenarios}->{ $_->{scenarioName} }->{steps_index}->{0} = 'Default';
foreach my $kpi (@{$scenario_detail->{kpis}}) {
$self->{scenarios}->{ $scenario->{scenarioName} }->{global}->{$kpi->{label}} = $kpi->{value};
}
$self->{scenarios}->{ $scenario->{scenarioName} }->{steps_index}->{0} = 'Default';
if ($scenario_detail->{infos}->{info}->{hasStep}) {
foreach my $steps (@{$scenario_detail->{steps}}) {
$self->{scenarios}->{ $_->{scenarioName} }->{steps_index}->{$steps->{index}} = $steps->{name};
$self->{scenarios}->{ $scenario->{scenarioName} }->{steps_index}->{$steps->{index} - 1} = $steps->{name};
}
}
foreach my $step_metrics (@{$scenario_detail->{results}}) {
my $exec_time = str2time($step_metrics->{planningTime}, 'GMT');
$self->{scenarios}->{ $_->{scenarioName} }->{steps}->{ $self->{scenarios}->{ $_->{scenarioName} }->{steps_index}->{ $step_metrics->{stepId} } }->{ $step_metrics->{metric} } = $step_metrics->{value};
$self->{scenarios}->{ $_->{scenarioName} }->{steps}->{ $self->{scenarios}->{ $_->{scenarioName} }->{steps_index}->{ $step_metrics->{stepId} } }->{last_exec} = POSIX::strftime('%d-%m-%Y %H:%M:%S %Z', localtime($exec_time));
$self->{scenarios}->{ $_->{scenarioName} }->{steps}->{ $self->{scenarios}->{ $_->{scenarioName} }->{steps_index}->{ $step_metrics->{stepId} } }->{display} = $self->{scenarios}->{ $_->{scenarioName} }->{steps_index}->{ $step_metrics->{stepId} };
$self->{scenarios}->{ $scenario->{scenarioName} }->{steps}->{ $self->{scenarios}->{ $scenario->{scenarioName} }->{steps_index}->{ $step_metrics->{stepId} } }->{ $step_metrics->{metric} } = $step_metrics->{value};
$self->{scenarios}->{ $scenario->{scenarioName} }->{steps}->{ $self->{scenarios}->{ $scenario->{scenarioName} }->{steps_index}->{ $step_metrics->{stepId} } }->{last_exec} = POSIX::strftime('%d-%m-%Y %H:%M:%S %Z', localtime($exec_time));
$self->{scenarios}->{ $scenario->{scenarioName} }->{steps}->{ $self->{scenarios}->{ $scenario->{scenarioName} }->{steps_index}->{ $step_metrics->{stepId} } }->{display} = $self->{scenarios}->{ $scenario->{scenarioName} }->{steps_index}->{ $step_metrics->{stepId} };
}
}
@ -244,7 +214,7 @@ __END__
=head1 MODE
Check IP Label Ekara scenarios.
Check ip-label Ekara scenarios.
=over 8
@ -253,28 +223,7 @@ Check IP Label Ekara scenarios.
Set timeframe period in seconds. (default: 900)
Example: --timeframe='3600' will check the last hour
=item B<--filter-id>
Filter by monitor ID (can be a regexp).
=item B<--filter-name>
Filter by monitor name (can be a regexp).
=item B<--filter-status>
Filter by numeric status (can be multiple).
0 => 'Unknown',
1 => 'Success',
2 => 'Failure',
3 => 'Aborted',
4 => 'No execution',
5 => 'No execution',
6 => 'Stopped',
7 => 'Excluded',
8 => 'Degraded'
Example: --filter-status='1,2'
=item B<--filter-type>

View File

@ -127,7 +127,7 @@ sub connect {
$self->{output}->exit();
}
if ($smtp_handle == -1) {
chomp $stdout;
chomp $stdout if (defined($stdout));
$self->{output}->output_add(
severity => $connection_exit,
short_msg => 'Unable to connect to SMTP: ' . (defined($stdout) ? $stdout : $error_msg)

View File

@ -112,7 +112,7 @@ sub request_api {
$self->{output}->option_exit();
}
if ($self->{http}->get_code() != 200) {
$self->{output}->add_option_msg(short_msg => "Connection issue: " . $decoded->{message});
$self->{output}->add_option_msg(short_msg => "Connection issue: " . defined($decoded->{message}) ? $decoded->{message} : '');
$self->{output}->option_exit();
}
@ -125,11 +125,11 @@ __END__
=head1 NAME
SFDC API boilerplate
Monitor SFDC API boilerplate
=head1 SYNOPSIS
Get informations from SFDC API
Get information from SFDC API
=head1 REST API OPTIONS
@ -137,15 +137,15 @@ Get informations from SFDC API
=item B<--hostname>
Set hostname to query (default: 'api.status.salesforce.com')
Define the hostname to query (default: C<api.status.salesforce.com>)
=item B<--timeout>
Set HTTP timeout in seconds (default: '10').
Define the HTTP timeout in seconds (default: '10').
=item B<--api-version>
API version (default: 'v1').
Define the API version (default: 'v1').
=back

View File

@ -18,7 +18,7 @@
# limitations under the License.
#
package network::huawei::snmp::mode::components::fan;
package centreon::common::huawei::standard::snmp::mode::components::fan;
use strict;
use warnings;

View File

@ -18,7 +18,7 @@
# limitations under the License.
#
package network::huawei::snmp::mode::components::temperature;
package centreon::common::huawei::standard::snmp::mode::components::temperature;
use strict;
use warnings;

View File

@ -18,7 +18,7 @@
# limitations under the License.
#
package network::huawei::snmp::mode::cpu;
package centreon::common::huawei::standard::snmp::mode::cpu;
use base qw(centreon::plugins::templates::counter);
@ -56,9 +56,7 @@ sub new {
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$options{options}->add_options(arguments =>
{
});
$options{options}->add_options(arguments => {});
return $self;
}
@ -80,17 +78,17 @@ sub manage_selection {
$self->{cpu} = {};
my $num = 1;
if (defined($results->{$oid_hwAvgDuty5min}) && scalar(keys %{$results->{$oid_hwAvgDuty5min}}) > 0) {
foreach (keys %{$results->{$oid_hwAvgDuty5min}}) {
foreach (sort keys %{$results->{$oid_hwAvgDuty5min}}) {
$self->{cpu}->{$num} = { num => $num, cpu => $results->{$oid_hwAvgDuty5min}->{$_} };
$num++;
}
} elsif (defined($results->{$oid_hwEntityCpuUsage}) && scalar(keys %{$results->{$oid_hwEntityCpuUsage}}) > 0) {
foreach (keys %{$results->{$oid_hwEntityCpuUsage}}) {
foreach (sort keys %{$results->{$oid_hwEntityCpuUsage}}) {
$self->{cpu}->{$num} = { num => $num, cpu => $results->{$oid_hwEntityCpuUsage}->{$_} };
$num++;
}
} else {
foreach (keys %{$results->{$oid_hwResOccupancy}}) {
foreach (sort keys %{$results->{$oid_hwResOccupancy}}) {
/\.([0-9]*?)$/;
next if (!defined($map_type->{$1}) || $map_type->{$1} ne 'cpu');
$self->{cpu}->{$num} = { num => $num, cpu => $results->{$oid_hwResOccupancy}->{$_} };

View File

@ -18,7 +18,7 @@
# limitations under the License.
#
package network::huawei::snmp::mode::hardware;
package centreon::common::huawei::standard::snmp::mode::hardware;
use base qw(centreon::plugins::templates::hardware);
@ -41,7 +41,7 @@ sub set_system {
]
};
$self->{components_path} = 'network::huawei::snmp::mode::components';
$self->{components_path} = 'centreon::common::huawei::standard::snmp::mode::components';
$self->{components_module} = ['fan', 'temperature'];
}

View File

@ -18,7 +18,7 @@
# limitations under the License.
#
package network::huawei::snmp::mode::interfaces;
package centreon::common::huawei::standard::snmp::mode::interfaces;
use base qw(snmp_standard::mode::interfaces);
@ -205,7 +205,7 @@ Check interface data volume between two checks (not supposed to be graphed, usef
=item B<--add-optical>
Check interface optical metrics.
Check interfaces' optical metrics.
=item B<--check-metrics>
@ -229,15 +229,182 @@ Set warning threshold for all error counters.
Set critical threshold for all error counters.
=item B<--warning-*> B<--critical-*>
=item B<--warning-total-port>
Thresholds (will superseed --[warning-critical]-errors).
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).
Thresholds.
=item B<--critical-total-port>
Thresholds.
=item B<--warning-total-admin-up>
Thresholds.
=item B<--critical-total-admin-up>
Thresholds.
=item B<--warning-total-admin-down>
Thresholds.
=item B<--critical-total-admin-down>
Thresholds.
=item B<--warning-total-oper-up>
Thresholds.
=item B<--critical-total-oper-up>
Thresholds.
=item B<--warning-total-oper-down>
Thresholds.
=item B<--critical-total-oper-down>
Thresholds.
=item B<--warning-in-traffic>
Thresholds.
=item B<--critical-in-traffic>
Thresholds.
=item B<--warning-out-traffic>
Thresholds.
=item B<--critical-out-traffic>
Thresholds.
=item B<--warning-in-error>
Thresholds.
=item B<--critical-in-error>
Thresholds.
=item B<--warning-in-discard>
Thresholds.
=item B<--critical-in-discard>
Thresholds.
=item B<--warning-out-error>
Thresholds.
=item B<--critical-out-error>
Thresholds.
=item B<--warning-out-discard>
Thresholds.
=item B<--critical-out-discard>
Thresholds.
=item B<--warning-in-ucast>
Thresholds.
=item B<--critical-in-ucast>
Thresholds.
=item B<--warning-in-bcast>
Thresholds.
=item B<--critical-in-bcast>
Thresholds.
=item B<--warning-in-mcast>
Thresholds.
=item B<--critical-in-mcast>
Thresholds.
=item B<--warning-out-ucast>
Thresholds.
=item B<--critical-out-ucast>
Thresholds.
=item B<--warning-out-bcast>
Thresholds.
=item B<--critical-out-bcast>
Thresholds.
=item B<--warning-out-mcast>
Thresholds.
=item B<--critical-out-mcast>
Thresholds.
=item B<--warning-speed>
Thresholds in b/s.
=item B<--critical-speed>
Thresholds in b/s.
=item B<--warning-input-power>
Thresholds in C<dBm>.
=item B<--critical-input-power>
Thresholds in C<dBm>.
=item B<--warning-bias-current>
Thresholds in C<mA>.
=item B<--critical-bias-current>
Thresholds in C<mA>.
=item B<--warning-output-power>
Thresholds in C<dBm>.
=item B<--critical-output-power>
Thresholds in C<dBm>.
=item B<--warning-module-temperature>
Thresholds in °C.
=item B<--critical-module-temperature>
Thresholds in °C.
And also: 'input-power' (dBm), 'bias-current' (mA), 'output-power' (dBm), 'module-temperature' (C).
=item B<--units-traffic>
@ -253,15 +420,20 @@ Units of thresholds for communication types (default: 'percent_delta') ('percent
=item B<--nagvis-perfdata>
Display traffic perfdata to be compatible with nagvis widget.
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').
Check only the interfaces with the specified IDs (OID indexes, e.g.: 1,2,...). If empty, all interfaces will be monitored.
To filter on interface names, see --name.
=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.
With this option, the interfaces will be filtered by name (given in option --interface) instead of OID index. The name matching mode supports regular expressions.
=item B<--regex-id>
With this option, interface IDs will be filtered using the --interface parameter as a regular expression instead of a list of IDs.
=item B<--speed>
@ -277,7 +449,7 @@ Set interface speed for outgoing traffic (in Mb).
=item B<--force-counters32>
Force to use 32 bits counters (even in snmp v2c and v3). Should be used when 64 bits counters are buggy.
Force to use 32-bit counters (even with SNMP versions 2c and 3). To use when 64 bits counters are buggy.
=item B<--reload-cache-time>

View File

@ -18,7 +18,7 @@
# limitations under the License.
#
package network::huawei::snmp::mode::memory;
package centreon::common::huawei::standard::snmp::mode::memory;
use base qw(centreon::plugins::templates::counter);
@ -30,21 +30,23 @@ sub custom_usage_perfdata {
if ($self->{result_values}->{total} > 0) {
$self->{output}->perfdata_add(
label => 'used', unit => 'B',
label => 'used', unit => 'B',
instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef,
value => $self->{result_values}->{used},
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1),
min => 0, max => $self->{result_values}->{total}
value => $self->{result_values}->{used},
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1),
min => 0,
max => $self->{result_values}->{total}
);
} else {
$self->{output}->perfdata_add(
label => 'used', unit => '%',
label => 'used', unit => '%',
instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef,
value => $self->{result_values}->{prct_used},
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
min => 0, max => 100
value => $self->{result_values}->{prct_used},
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
min => 0,
max => 100
);
}
}
@ -52,7 +54,13 @@ sub custom_usage_perfdata {
sub custom_usage_threshold {
my ($self, %options) = @_;
my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]);
my $exit = $self->{perfdata}->threshold_check(
value => $self->{result_values}->{prct_used},
threshold => [
{ label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' },
{ label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' }
]
);
return $exit;
}
@ -66,10 +74,12 @@ sub custom_usage_output {
my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free});
$msg = sprintf("Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)",
$total_size_value . " " . $total_size_unit,
$total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used},
$total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free});
$total_size_value . " " . $total_size_unit,
$total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used},
$total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}
);
}
return $msg;
}
@ -77,9 +87,9 @@ sub custom_usage_calc {
my ($self, %options) = @_;
$self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'};
$self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'};
$self->{result_values}->{free} = $options{new_datas}->{$self->{instance} . '_free'};
$self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_total'} - $self->{result_values}->{free};
$self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'};
$self->{result_values}->{free} = $options{new_datas}->{$self->{instance} . '_free'};
$self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_total'} - $self->{result_values}->{free};
if ($self->{result_values}->{total} > 0) {
$self->{result_values}->{prct_free} = $self->{result_values}->{free} * 100 / $self->{result_values}->{total};
@ -87,6 +97,7 @@ sub custom_usage_calc {
} else {
$self->{result_values}->{prct_used} = $options{new_datas}->{$self->{instance} . '_used_prct'};
}
return 0;
}
@ -99,11 +110,11 @@ sub set_counters {
$self->{maps_counters}->{memory} = [
{ label => 'usage', set => {
key_values => [ { name => 'display' }, { name => 'used_prct' }, { name => 'free' }, { name => 'total' } ],
closure_custom_calc => $self->can('custom_usage_calc'),
closure_custom_output => $self->can('custom_usage_output'),
closure_custom_perfdata => $self->can('custom_usage_perfdata'),
closure_custom_threshold_check => $self->can('custom_usage_threshold'),
key_values => [ { name => 'display' }, { name => 'used_prct' }, { name => 'free' }, { name => 'total' } ],
closure_custom_calc => $self->can('custom_usage_calc'),
closure_custom_output => $self->can('custom_usage_output'),
closure_custom_perfdata => $self->can('custom_usage_perfdata'),
closure_custom_threshold_check => $self->can('custom_usage_threshold'),
}
},
];
@ -120,16 +131,14 @@ sub new {
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$options{options}->add_options(arguments =>
{
});
$options{options}->add_options(arguments => {});
return $self;
}
my $oid_hwEntityMemUsage = '.1.3.6.1.4.1.2011.5.25.31.1.1.1.1.7'; # prct
my $oid_hwMemoryDevEntry = '.1.3.6.1.4.1.2011.6.3.5.1.1';
my $oid_hwResOccupancy = '.1.3.6.1.4.1.2011.6.3.17.1.1.3';
my $oid_hwResOccupancy = '.1.3.6.1.4.1.2011.6.3.17.1.1.3';
my $map_type = { 1 => 'memory', 2 => 'messageUnits', 3 => 'cpu' };
my $mapping = {
@ -149,19 +158,19 @@ sub manage_selection {
my $num = 1;
if (defined($results->{$oid_hwMemoryDevEntry}) && scalar(keys %{$results->{$oid_hwMemoryDevEntry}}) > 0) {
foreach (keys %{$results->{$oid_hwMemoryDevEntry}}) {
foreach (sort keys %{$results->{$oid_hwMemoryDevEntry}}) {
next if (!/^$mapping->{hwMemoryDevFree}->{oid}\.(.*)$/);
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results->{$oid_hwMemoryDevEntry}, instance => $1);
$self->{memory}->{$num} = { display => $num, used_prct => -1, free => $result->{hwMemoryDevFree}, total => $result->{hwMemoryDevSize} };
$num++;
}
} elsif (defined($results->{$oid_hwEntityMemUsage}) && scalar(keys %{$results->{$oid_hwEntityMemUsage}}) > 0) {
foreach (keys %{$results->{$oid_hwEntityMemUsage}}) {
foreach (sort keys %{$results->{$oid_hwEntityMemUsage}}) {
$self->{memory}->{$num} = { display => $num, used_prct => $results->{$oid_hwEntityMemUsage}->{$_}, free => 0, total => 0 };
$num++;
}
} else {
foreach (keys %{$results->{$oid_hwResOccupancy}}) {
foreach (sort keys %{$results->{$oid_hwResOccupancy}}) {
/\.([0-9]*?)$/;
next if (!defined($map_type->{$1}) || $map_type->{$1} ne 'memory');
$self->{memory}->{$num} = { display => $num, used_prct => $results->{$oid_hwResOccupancy}->{$_}, free => 0, total => 0 };

View File

@ -45,6 +45,7 @@ sub new {
'change-exit:s@' => { name => 'change_exit' },
'change-short-output:s@' => { name => 'change_short_output' },
'change-long-output:s@' => { name => 'change_long_output' },
'change-output-adv:s@' => { name => 'change_output_adv' },
'use-new-perfdata' => { name => 'use_new_perfdata' },
'filter-uom:s' => { name => 'filter_uom' },
'verbose' => { name => 'verbose' },
@ -124,6 +125,29 @@ sub check_options {
}
}
if (defined($self->{option_results}->{change_output_adv})) {
foreach (@{$self->{option_results}->{change_output_adv}}) {
my ($expr, $short_output, $exit_code) = split /,/;
next if (!defined($expr) || $expr eq '');
$expr =~ s/%\{(.*?)\}/\$values->{$1}/g;
$expr =~ s/%\((.*?)\)/\$values->{$1}/g;
if ( defined($exit_code) && $exit_code ne '' && defined( $self->{errors}->{uc($exit_code)} ) ) {
$exit_code = uc($exit_code);
} else {
$exit_code = undef;
}
$self->{change_output_adv} = [] if (!defined($self->{change_output_adv}));
push @{$self->{change_output_adv}}, {
expr => $expr,
short_output => $short_output,
exit_code => $exit_code
};
}
}
if (defined($self->{option_results}->{change_exit})) {
$self->{change_exit} = {};
foreach (@{$self->{option_results}->{change_exit}}) {
@ -211,6 +235,7 @@ sub output_add {
push @{$self->{global_short_outputs}->{uc($options->{severity})}}, $options->{short_msg};
$self->set_status(exit_litteral => $options->{severity});
}
if (defined($options->{long_msg})) {
chomp $options->{long_msg};
@ -483,7 +508,8 @@ sub output_txt_short_display {
sub output_txt_short {
my ($self, %options) = @_;
if (!defined($self->{option_results}->{change_short_output})) {
if (!defined($self->{option_results}->{change_short_output}) &&
!defined($self->{change_output_adv})) {
$self->output_txt_short_display(%options);
return ;
}
@ -503,6 +529,18 @@ sub output_txt_short {
eval "\$stdout =~ s{$pattern}{$replace}$modifier";
}
my $exit = defined($options{exit_litteral}) ? uc($options{exit_litteral}) : uc($self->{myerrors}->{ $self->{global_status} });
foreach (@{$self->{change_output_adv}}) {
if ($self->test_eval(test => $_->{expr}, values => { short_output => $stdout, exit_code => $self->{errors}->{$exit} })) {
if (defined($_->{short_output}) && $_->{short_output} ne '') {
$stdout = $_->{short_output};
}
if (defined($_->{exit_code}) && $_->{exit_code} ne '') {
$self->{coa_save_exit_code} = $_->{exit_code};
}
}
}
print $stdout;
}
@ -512,6 +550,7 @@ sub output_txt {
my $force_long_output = (defined($options{force_long_output}) && $options{force_long_output} == 1) ? 1 : 0;
return if ($self->{nodisplay} == 1);
if (defined($self->{global_short_concat_outputs}->{UNQUALIFIED_YET})) {
$self->output_add(severity => uc($options{exit_litteral}), short_msg => $self->{global_short_concat_outputs}->{UNQUALIFIED_YET});
}
@ -689,6 +728,10 @@ sub exit {
} else {
$exit = $self->{myerrors}->{ $self->{global_status} };
}
if (defined($self->{coa_save_exit_code})) {
$exit = $self->{coa_save_exit_code};
}
if (defined($self->{change_exit}) && defined($self->{change_exit}->{$exit})) {
$exit = $self->{change_exit}->{$exit};
}
@ -1538,15 +1581,14 @@ remove all metrics whose value equals 0 and that don't have a maximum value.
=item B<--explode-perfdata-max>
Create a new metric for each metric that comes with a maximum limit. The new
metric will be named identically with a '_max' suffix).
metric will be named identically with a '_max' suffix.
Example: it will split 'used_prct'=26.93%;0:80;0:90;0;100
into 'used_prct'=26.93%;0:80;0:90;0;100 'used_prct_max'=100%;;;;
=item B<--change-perfdata> B<--extend-perfdata>
Change or extend perfdata.
Syntax: --extend-perfdata=searchlabel,newlabel,target[,[newuom],[min],[max]]
Syntax: --extend-perfdata=searchlabel,newlabel,target[,[<new-unit-of-mesure>],[min],[max]]
Common examples:
@ -1567,11 +1609,11 @@ Change traffic values in percent: --change-perfdata='traffic_in,,percent()'
=item B<--extend-perfdata-group>
Add new aggregated metrics (min, max, average or sum) for groups of metrics defined by a regex match on the metrics' names.
Syntax: --extend-perfdata-group=regex,namesofnewmetrics,calculation[,[newuom],[min],[max]]
Syntax: --extend-perfdata-group=regex,<names-of-new-metrics>,calculation[,[<new-unit-of-mesure>],[min],[max]]
regex: regular expression
namesofnewmetrics: how the new metrics' names are composed (can use $1, $2... for groups defined by () in regex).
<names-of-new-metrics>: how the new metrics' names are composed (can use $1, $2... for groups defined by () in regex).
calculation: how the values of the new metrics should be calculated
newuom (optional): unit of measure for the new metrics
<new-unit-of-mesure> (optional): unit of measure for the new metrics
min (optional): lowest value the metrics can reach
max (optional): highest value the metrics can reach
@ -1598,6 +1640,14 @@ Replace an exit code with one of your choice.
Example: adding --change-exit=unknown=critical will result in a CRITICAL state
instead of an UNKNOWN state.
=item B<--change-output-adv>
Replace short output and exit code based on a "if" condition using the following variables:
short_output, exit_code.
Variables must be written either %{variable} or %(variable).
Example: adding --change-output-adv='%(short_ouput) =~ /UNKNOWN: No daemon/,OK: No daemon,OK' will
change the following specific UNKNOWN result to an OK result.
=item B<--range-perfdata>
Rewrite the ranges displayed in the perfdata. Accepted values:
@ -1640,8 +1690,8 @@ format).
=item B<--output-file>
Write output in file (can be combined with json, xml and openmetrics options).
E.g.: --output-file=/tmp/output.txt will write the output in /tmp/output.txt.
Write output in file (can be combined with JSON, XML and OpenMetrics options).
Example: --output-file=/tmp/output.txt will write the output in /tmp/output.txt.
=item B<--disco-format>

View File

@ -65,6 +65,7 @@ sub new {
my $mapping = {
onLogicalLogDbspace => { oid => '.1.3.6.1.4.1.893.1.1.1.8.1.3' },
onLogicalLogStatus => { oid => '.1.3.6.1.4.1.893.1.1.1.8.1.4' },
onLogicalLogPagesAllocated => { oid => '.1.3.6.1.4.1.893.1.1.1.8.1.7' },
onLogicalLogPagesUsed => { oid => '.1.3.6.1.4.1.893.1.1.1.8.1.8' },
};
@ -76,6 +77,7 @@ sub manage_selection {
my $snmp_result = $options{snmp}->get_multiple_table(oids => [
{ oid => $oid_applName },
{ oid => $mapping->{onLogicalLogDbspace}->{oid} },
{ oid => $mapping->{onLogicalLogStatus}->{oid} },
{ oid => $mapping->{onLogicalLogPagesAllocated}->{oid} },
{ oid => $mapping->{onLogicalLogPagesUsed}->{oid} },
], return_type => 1, nothing_quit => 1
@ -103,7 +105,17 @@ sub manage_selection {
}
$self->{global}->{$name}->{allocated} += $result->{onLogicalLogPagesAllocated};
$self->{global}->{$name}->{used} += $result->{onLogicalLogPagesUsed};
# Status of the logical-log file:
# newlyAdded (1)
# free (2)
# current (3)
# used (4)
# backedUpButNeeded (5)
# consider log files with state backedUpButNeeded as free space
if ($result->{onLogicalLogStatus} != 5) {
$self->{global}->{$name}->{used} += $result->{onLogicalLogPagesUsed};
}
}
foreach (keys %{$self->{global}}) {
@ -128,7 +140,8 @@ Check log files usage.
=item B<--filter-name>
Filter dbspace name (can be a regexp).
Define which C<dbspace> should be monitored based on their names.
This option will be treated as a regular expression.
=item B<--warning-usage>

View File

@ -24,8 +24,8 @@ use strict;
use warnings;
my %map_fan_status = (
0 => 'ok',
1 => 'failed',
1 => 'ok',
2 => 'failure',
);
my $mapping = {

View File

@ -29,7 +29,7 @@ my %map_psu_status = (
);
my $mapping = {
axisPsState => { oid => '.1.3.6.1.4.1.368.4.1.2.1.3', map => \%map_psu_status },
axisPsState => { oid => '.1.3.6.1.4.1.368.4.1.1.1.3', map => \%map_psu_status },
};
sub load {

View File

@ -0,0 +1,48 @@
package hardware::server::lenovo::xcc::snmp::mode::components::cpu;
use strict;
use warnings FATAL => 'all';
use strict;
use warnings;
use centreon::plugins::misc;
my $mapping = {
cpuStatus => { oid => '.1.3.6.1.4.1.19046.11.1.1.5.20.1.11' },
cpuString => { oid => '.1.3.6.1.4.1.19046.11.1.1.5.20.1.2' },
};
my $oid_cpuEntry = '.1.3.6.1.4.1.19046.11.1.1.5.20.1';
sub load {
my ($self) = @_;
push @{$self->{request}}, { oid => $oid_cpuEntry };
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking cpu");
$self->{components}->{cpu} = { name => 'cpu', total => 0, skip => 0 };
return if ($self->check_filter(section => 'cpu'));
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_cpuEntry}})) {
next if ($oid !~ /^$mapping->{cpuString}->{oid}\.(.*)$/);
my $instance = $1;
my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_cpuEntry}, instance => $instance);
next if ($self->check_filter(section => 'cpu', instance => $instance));
$result->{cpuStatus} = centreon::plugins::misc::trim($result->{cpuStatus});
$self->{components}->{cpu}->{total}++;
$self->{output}->output_add(long_msg => sprintf("'%s' status is %s [instance: %s].",
$result->{cpuString}, $result->{cpuStatus}, $instance));
my $exit = $self->get_severity(label => 'default', section => 'default', value => $result->{cpuStatus});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("'%s' cpu status for '%s'", $result->{cpuStatus}, $result->{cpuString}));
}
}
}
1;

View File

@ -0,0 +1,68 @@
#
# 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 hardware::server::lenovo::xcc::snmp::mode::components::health;
use Data::Dumper;
use strict;
use warnings;
use centreon::plugins::misc;
my $mapping = {
healthStatus => { oid => '.1.3.6.1.4.1.19046.11.1.1.4.2.1.2' },
healthString => { oid => '.1.3.6.1.4.1.19046.11.1.1.4.2.1.3' },
};
my $oid_healthEntry = '.1.3.6.1.4.1.19046.11.1.1.4.2.1';
sub load {
my ($self) = @_;
push @{$self->{request}}, { oid => $oid_healthEntry };
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking health");
$self->{components}->{health} = { name => 'health', total => 0, skip => 0 };
return if ($self->check_filter(section => 'health'));
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_healthEntry}})) {
next if ($oid !~ /^$mapping->{healthString}->{oid}\.(.*)$/);
my $instance = $1;
my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_healthEntry}, instance => $instance);
next if ($self->check_filter(section => 'health', instance => $instance));
$result->{healthStatus} = centreon::plugins::misc::trim($result->{healthStatus});
$self->{components}->{health}->{total}++;
$self->{output}->output_add(long_msg => sprintf("health '%s' status is %s [instance: %s].",
$result->{healthString}, $result->{healthStatus}, $instance));
my $exit = $self->get_severity(label => 'default', section => 'default', value => $result->{healthStatus});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("'%s' health status for '%s'", $result->{healthStatus}, $result->{healthString}));
}
}
}
1;

View File

@ -0,0 +1,48 @@
package hardware::server::lenovo::xcc::snmp::mode::components::memory;
use strict;
use warnings;
use strict;
use warnings;
use centreon::plugins::misc;
my $mapping = {
memoryStatus => { oid => '.1.3.6.1.4.1.19046.11.1.1.5.21.1.8' },
memoryString => { oid => '.1.3.6.1.4.1.19046.11.1.1.5.21.1.2' },
};
my $oid_memoryEntry = '.1.3.6.1.4.1.19046.11.1.1.5.21.1';
sub load {
my ($self) = @_;
push @{$self->{request}}, { oid => $oid_memoryEntry };
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking memory");
$self->{components}->{memory} = { name => 'memory', total => 0, skip => 0 };
return if ($self->check_filter(section => 'memory'));
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_memoryEntry}})) {
next if ($oid !~ /^$mapping->{memoryString}->{oid}\.(.*)$/);
my $instance = $1;
my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_memoryEntry}, instance => $instance);
next if ($self->check_filter(section => 'memory', instance => $instance));
$result->{memoryStatus} = centreon::plugins::misc::trim($result->{memoryStatus});
$self->{components}->{memory}->{total}++;
$self->{output}->output_add(long_msg => sprintf("'%s' status is %s [instance: %s].",
$result->{memoryString}, $result->{memoryStatus}, $instance));
my $exit = $self->get_severity(label => 'default', section => 'default', value => $result->{memoryStatus});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("'%s' memory status for '%s'", $result->{memoryStatus}, $result->{memoryString}));
}
}
}
1;

View File

@ -33,18 +33,19 @@ sub set_system {
$self->{cb_hook2} = 'snmp_execute';
$self->{thresholds} = {
default => [
default => [
['Normal', 'OK'],
['.*', 'CRITICAL']
],
raidvolume => [
['Optimal', 'OK'],
['.*', 'CRITICAL']
]
],
};
$self->{components_path} = 'hardware::server::lenovo::xcc::snmp::mode::components';
$self->{components_module} = ['temperature', 'voltage', 'fan', 'psu', 'disk', 'raidvolume'];
$self->{components_module} = ['temperature', 'voltage', 'fan', 'psu', 'disk', 'raidvolume', 'health', 'cpu', 'memory'];
}
sub snmp_execute {
@ -77,7 +78,7 @@ Check hardware.
=item B<--component>
Which component to check (default: '.*').
Can be: 'temperature', 'voltage', 'fan', 'psu', 'disk', 'raidvolume'.
Can be: 'temperature', 'voltage', 'fan', 'psu', 'disk', 'raidvolume', 'health', 'cpu', 'memory'.
=item B<--filter>

View File

@ -64,8 +64,8 @@ sub check_options {
command => $self->{option_results}->{command_plink}
);
$self->{option_results}->{command} = 'plink'
if (!defined($self->{option_results}->{command}) || $self->{option_results}->{command} eq '');
$self->{option_results}->{command_plink} = 'plink'
if (!defined($self->{option_results}->{command_plink}) || $self->{option_results}->{command_plink} eq '');
}
sub run {
@ -132,25 +132,25 @@ __END__
=head1 MODE
Check Sun 'T1xxx', 'T2xxx' Hardware (through ALOM4v).
Check Sun C<T1xxx>, C<T2xxx> management cards hardware (using C<ALOM4v>).
=over 8
=item B<--hostname>
Hostname to query.
Define the hostname to query.
=item B<--username>
ssh username.
Define the ssh username.
=item B<--password>
ssh password.
Define the ssh password.
=item B<--command-plink>
Plink command (default: plink). Use to set a path.
Define the C<plink> command (default: C<plink>).
=item B<--timeout>

View File

@ -71,8 +71,8 @@ sub check_options {
command => $self->{option_results}->{command_plink}
);
$self->{option_results}->{command} = 'plink'
if (!defined($self->{option_results}->{command}) || $self->{option_results}->{command} eq '');
$self->{option_results}->{command_plink} = 'plink'
if (!defined($self->{option_results}->{command_plink}) || $self->{option_results}->{command_plink} eq '');
}
sub run {
@ -185,30 +185,30 @@ __END__
=head1 MODE
Check Sun 'T3-x', 'T4-x' and 'T5xxx' Hardware (through ILOM).
Check Sun C<T3-x>, C<T4-x> and C<T5xxx> management cards hardware (using C<ILOM>).
=over 8
=item B<--hostname>
Hostname to query.
Define the hostname to query.
=item B<--username>
ssh username.
Define the ssh username.
=item B<--password>
ssh password.
Define the ssh password.
=item B<--command-plink>
Define the C<plink> command (default: C<plink>).
=item B<--memory>
Returns new errors (retention file is used by the following option).
=item B<--command-plink>
Plink command (default: plink). Use to set a path.
=item B<--timeout>
Timeout in seconds for the command (default: 30).

View File

@ -0,0 +1,312 @@
#
# Copyright 2023 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package network::aruba::aoscx::snmp::mode::stack;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use Digest::MD5 qw(md5_hex);
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold catalog_status_calc);
sub custom_member_status_output {
my ($self, %options) = @_;
my $msg = sprintf(
'role: %s [state: %s]',
$self->{result_values}->{role},
$self->{result_values}->{state},
);
return $msg;
}
sub custom_member_status_calc {
my ($self, %options) = @_;
$self->{result_values}->{roleLast} = $options{old_datas}->{$self->{instance} . '_role'};
$self->{result_values}->{role} = $options{new_datas}->{$self->{instance} . '_role'};
$self->{result_values}->{stateLast} = $options{old_datas}->{$self->{instance} . '_state'};
$self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'};
if (!defined($options{old_datas}->{$self->{instance} . '_role'})) {
$self->{error_msg} = "buffer creation";
return -2;
}
return 0;
}
sub custom_port_status_output {
my ($self, %options) = @_;
my $msg = sprintf(
'operational status: %s [admin status: %s]',
$self->{result_values}->{oper_status},
$self->{result_values}->{admin_status}
);
return $msg;
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'member',
type => 3,
cb_prefix_output => 'prefix_member_output',
cb_long_output => 'member_long_output',
indent_long_output => ' ',
message_multiple => 'All stack members are ok',
group =>
[
{ name => 'global', type => 0, skipped_code => { -10 => 1 } },
{ name => 'port',
display_long => 1,
cb_prefix_output => 'prefix_port_output',
message_multiple => 'All ports are ok',
type => 1,
skipped_code => { -10 => 1 } },
]
}
];
$self->{maps_counters}->{global} = [
{ label => 'member-status', threshold => 0, set => {
key_values => [ { name => 'role' }, { name => 'display' }, { name => 'state'} ],
closure_custom_calc => $self->can('custom_member_status_calc'),
closure_custom_output => $self->can('custom_member_status_output'),
closure_custom_perfdata => sub {return 0;},
closure_custom_threshold_check => \&catalog_status_threshold,
}
},
];
$self->{maps_counters}->{port} = [
{ label => 'port-status', threshold => 0, set => {
key_values =>
[ { name => 'oper_status' }, { name => 'admin_status' }, { name => 'display' } ],
closure_custom_calc => \&catalog_status_calc,
closure_custom_output => $self->can('custom_port_status_output'),
closure_custom_perfdata => sub {return 0;},
closure_custom_threshold_check => \&catalog_status_threshold,
}
},
];
}
sub member_long_output {
my ($self, %options) = @_;
return "checking stack member '" . $options{instance_value}->{display} . "'";
}
sub prefix_member_output {
my ($self, %options) = @_;
return "Stack member '" . $options{instance_value}->{display} . "' ";
}
sub prefix_port_output {
my ($self, %options) = @_;
return "port '" . $options{instance_value}->{display} . "' ";
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
'unknown-member-status:s' => { name => 'unknown_member_status', default => '' },
'warning-member-status:s' => { name => 'warning_member_status', default => '' },
'critical-member-status:s' => { name => 'critical_member_status', default => '%{role} ne %{roleLast}' },
'unknown-port-status:s' => { name => 'unknown_port_status', default => '' },
'warning-port-status:s' => { name => 'warning_port_status', default => '' },
'critical-port-status:s' => {
name => 'critical_port_status',
default => '%{admin_status} eq "up" and %{oper_status} ne "up"'
},
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
$self->change_macros(
macros => [
'unknown_member_status', 'warning_member_status', 'critical_member_status',
'unknown_port_status', 'warning_port_status', 'critical_port_status'
]
);
}
my $map_member_state = {
0 => 'unusedId',
1 => 'missing',
2 => 'provision',
3 => 'commander',
4 => 'standby',
5 => 'member',
6 => 'shutdown',
7 => 'booting',
8 => 'communicationFailure',
9 => 'incompatibleOs',
10 => 'unknownState',
11 => 'standbyBooting'
};
my $map_member_role_status = {
1 => 'active',
2 => 'notInService',
3 => 'notReady',
4 => 'createAndGo',
5 => 'createAndWait',
6 => 'destroy'
};
my $map_port_admin_status = {
1 => 'enabled',
2 => 'disabled'
};
my $map_port_operation_status = {
1 => 'up',
2 => 'down',
3 => 'disabled',
4 => 'blocked'
};
my $mapping_member_table = {
stackMemberSerialNum => { oid => '.1.3.6.1.4.1.11.2.14.11.5.1.116.1.3.1.14' },
stackMemberRoleStatus => { oid => '.1.3.6.1.4.1.11.2.14.11.5.1.116.1.3.1.7', map => $map_member_role_status },
stackMemberState => { oid => '.1.3.6.1.4.1.11.2.14.11.5.1.116.1.3.1.9', map => $map_member_state },
};
my $mapping_port_table = {
stackPortAdminStatus => { oid => '.1.3.6.1.4.1.11.2.14.11.5.1.116.1.5.1.8', map => $map_port_admin_status },
stackPortOperStatus => { oid => '.1.3.6.1.4.1.11.2.14.11.5.1.116.1.5.1.3', map => $map_port_operation_status }
};
my $oid_memberTableEntry = '.1.3.6.1.4.1.11.2.14.11.5.1.116.1.3.1';
my $oid_portTableEntry = '.1.3.6.1.4.1.11.2.14.11.5.1.116.1.5.1';
sub manage_selection {
my ($self, %options) = @_;
$self->{member} = {};
my $snmp_result = $options{snmp}->get_multiple_table(
oids => [
{ oid => $oid_memberTableEntry },
{ oid => $mapping_member_table->{stackMemberSerialNum}->{oid} },
{ oid => $mapping_member_table->{stackMemberRoleStatus}->{oid} },
{ oid => $mapping_member_table->{stackMemberState}->{oid} }
,
{ oid => $oid_portTableEntry },
{ oid => $mapping_port_table->{stackPortAdminStatus}->{oid} },
{ oid => $mapping_port_table->{stackPortOperStatus}->{oid} },
,
],
nothing_quit => 1
);
foreach my $oid (keys %{$snmp_result->{$oid_memberTableEntry}}) {
next if ($oid !~ /^$mapping_member_table->{stackMemberRoleStatus}->{oid}\.(.*)$/);
my $instance_id = $1;
my $result = $options{snmp}->map_instance(
mapping => $mapping_member_table,
results => $snmp_result->{$oid_memberTableEntry},
instance => $instance_id);
$self->{member}->{$result->{stackMemberSerialNum}} = {
display => $result->{stackMemberSerialNum},
global => {
display => $result->{stackMemberSerialNum},
role => $result->{stackMemberRoleStatus},
state => $result->{stackMemberState},
},
port => {},
};
foreach (keys %{$snmp_result->{$oid_portTableEntry}}) {
next if (!/^$mapping_port_table->{stackPortOperStatus}->{oid}\.$instance_id\.(.*?)\.(.*)$/);
my $port_name = $1;
my $result2 = $options{snmp}->map_instance(
mapping => $mapping_port_table,
results => $snmp_result->{$oid_portTableEntry},
instance => $instance_id . '.' . $port_name . '.1');
$self->{member}->{$result->{stackMemberSerialNum}}->{port}->{$port_name} = {
display => $port_name,
admin_status => $result2->{stackPortAdminStatus},
oper_status => $result2->{stackPortOperStatus},
};
}
}
$self->{cache_name} = "aruba_aoscx_" . $self->{mode} . '_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' .
(defined($self->{option_results}->{filter_counters}) ?
md5_hex($self->{option_results}->{filter_counters}) :
md5_hex('all'));
}
1;
__END__
=head1 MODE
Check stack members.
=over 8
=item B<--unknown-member-status>
Define the conditions to match for the status to be UNKNOWN (Default: '').
You can use the following variables: %{role}, %{roleLast}, %{state}, %{stateLast}
=item B<--warning-member-status>
Define the conditions to match for the status to be WARNING (Default: '').
You can use the following variables: %{role}, %{roleLast}, %{state}, %{stateLast}
=item B<--critical-member-status>
Define the conditions to match for the status to be CRITICAL (Default: '%{role} ne %{roleLast}').
You can use the following variables: %{role}, %{roleLast}, %{state}, %{stateLast}
=item B<--unknown-port-status>
Define the conditions to match for the status to be UNKNOWN (Default: '').
You can use the following variables: %{admin_status}, %{oper_status}, %{display}
=item B<--warning-port-status>
Define the conditions to match for the status to be WARNING (Default: '').
You can use the following variables: %{admin_status}, %{oper_status}, %{display}
=item B<--critical-port-status>
Define the conditions to match for the status to be CRITICAL (Default: '%{admin_status} eq "up" and %{oper_status} ne "up"').
You can use the following variables: %{admin_status}, %{oper_status}, %{display}
=back
=cut

View File

@ -35,6 +35,7 @@ sub new {
'interfaces' => 'snmp_standard::mode::interfaces',
'list-interfaces' => 'snmp_standard::mode::listinterfaces',
'memory' => 'network::aruba::aoscx::snmp::mode::memory',
'stack' => 'network::aruba::aoscx::snmp::mode::stack',
'vsf' => 'network::aruba::aoscx::snmp::mode::vsf',
'vsx' => 'network::aruba::aoscx::snmp::mode::vsx'
};

View File

@ -45,7 +45,7 @@ Check system CPUs.
=item B<--use-ucd>
Use UCD mib for CPU average.
Use UCD MIB for CPU average.
=item B<--warning-average>

View File

@ -149,10 +149,11 @@ sub request {
$self->settings();
my $content = $self->{http}->request(
method => 'GET',
method => $options{method},
url_path => $endpoint,
get_param => $options{get_param},
header => [
'Accept: application/json',
'AUTH: ' . $self->{api_token}
],
warning_status => '',
@ -163,9 +164,11 @@ sub request {
# Maybe there is an issue with the token. So we retry.
if ($self->{http}->get_code() < 200 || $self->{http}->get_code() >= 300) {
$content = $self->{http}->request(
method => $options{method},
url_path => $endpoint,
get_param => $options{get_param},
header => [
'Accept: application/json',
'AUTH: ' . $self->{api_token}
],
unknown_status => $self->{unknown_http_status},
@ -179,7 +182,6 @@ sub request {
$self->{output}->add_option_msg(short_msg => 'Error while retrieving data (add --debug option for detailed message)');
$self->{output}->option_exit();
}
return $decoded;
}
@ -190,7 +192,8 @@ sub get_backup_jobs_status {
if (!centreon::plugins::misc::is_empty($options{filter_type})) {
$endpoint .= '/' . $options{filter_type};
}
return $self->request(endpoint => $endpoint);
return $self->request(method => 'GET',
endpoint => $endpoint);
}
sub get_config_status {
@ -200,7 +203,8 @@ sub get_config_status {
if (!centreon::plugins::misc::is_empty($options{filter_type})) {
$endpoint .= '/' . $options{filter_type};
}
return $self->request(endpoint => $endpoint);
return $self->request(method => 'GET',
endpoint => $endpoint);
}
sub get_intelli_check_status {
@ -213,7 +217,49 @@ sub get_intelli_check_status {
if (!centreon::plugins::misc::is_empty($options{report_id})) {
$endpoint .= '/' . $options{report_id};
}
return $self->request(endpoint => $endpoint);
return $self->request(method => 'GET',
endpoint => $endpoint);
}
sub get_devices {
my ($self, %options) = @_;
my $json_decode = 1;
if (defined($options{json_decode})) {
$json_decode = $options{json_decode};
}
return $self->request(method => 'GET',
endpoint => 'devices');
}
sub get_device_id_from_name {
my ($self, %options) = @_;
my $devices = $self->get_devices();
for my $device (@$devices) {
if ($device->{deviceName} eq $options{device_name}) {
return $device->{deviceId};
}
}
}
sub get_devices_backups_status {
my ($self, %options) = @_;
return $self->request(method => 'POST',
endpoint => 'devices/dynamic');
}
sub get_device_backup_status {
my ($self, %options) = @_;
my $backups = $self->get_devices_backups_status();
for my $backup (@$backups) {
if ($backup->{deviceId} == $options{device_id}) {
return $backup;
}
}
}
1;

View File

@ -24,7 +24,6 @@ use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
sub prefix_backup_output {
my ($self, %options) = @_;

View File

@ -24,7 +24,6 @@ use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
sub set_counters {
my ($self, %options) = @_;

View File

@ -0,0 +1,143 @@
#
# 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 network::backbox::restapi::mode::devicebackup;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
sub custom_status_output {
my ($self, %options) = @_;
my $msg = sprintf("Device [id: %s] [name: %s] [status: %s] [status reason: %s]",
$self->{result_values}->{device_id},
$self->{result_values}->{device_name},
$self->{result_values}->{status},
$self->{result_values}->{status_reason});
return $msg;
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'backup', type => 0 },
];
$self->{maps_counters}->{backup} = [
{ label => 'status',
type => 2,
warning_default => '%{status} =~ /SUSPECT/i',
critical_default => '%{status} =~ /FAILURE/i',
set => {
key_values => [ { name => 'device_id' },
{ name => 'device_name' },
{ name => 'status' },
{ name => 'status_reason' }
],
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
'device-id:s' => { name => 'device_id' },
'device-name:s' => { name => 'device_name' }
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
if (centreon::plugins::misc::is_empty($self->{option_results}->{device_id}) && centreon::plugins::misc::is_empty($self->{option_results}->{device_name})) {
$self->{output}->add_option_msg(short_msg => "Need to specify --device-id or --device-name option.");
$self->{output}->option_exit();
}
}
sub manage_selection {
my ($self, %options) = @_;
my $device_id = $self->{option_results}->{device_id};
my $device_name = $self->{option_results}->{device_name} || '';
if (centreon::plugins::misc::is_empty($device_id)) {
$device_id = $options{custom}->get_device_id_from_name(device_name => $device_name);
}
my $backup = $options{custom}->get_device_backup_status(device_id => $device_id);
if (centreon::plugins::misc::is_empty($backup)) {
$self->{output}->add_option_msg(short_msg => "No backup found for device id '" . $device_id . "'.");
$self->{output}->option_exit();
}
$self->{backup} = { device_id => $device_id,
device_name => $device_name,
status => $backup->{historyStatus},
status_reason => $backup->{statusReason}
};
}
1;
__END__
=head1 MODE
Check a device backup on BackBox.
=over 8
=item B<--device-id>
ID of the device (if you prefer to use the ID instead of the name).
ID or name is mandatory.
=item B<--device-name>
Name of the device (if you prefer to use the name instead of the ID).
ID or name is mandatory. If you specify both, the ID will be used.
=item B<--warning-status>
Set warning threshold for status (Default: '%{status} =~ /SUSPECT/i').
You can use the following variables: %{status}, %{status_reason}, %{device_name}, %{device_id}.
=item B<--critical-status>
Set critical threshold for status (Default: '%{status} =~ /FAILURE/i').
You can use the following variables: %{status}, %{status_reason}, %{device_name}, %{device_id}.
=back
=cut

View File

@ -24,7 +24,6 @@ use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
sub prefix_intellicheck_output {
my ($self, %options) = @_;

View File

@ -0,0 +1,121 @@
#
# 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 network::backbox::restapi::mode::listdevices;
use strict;
use warnings;
use base qw(centreon::plugins::mode);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
sub run {
my ($self, %options) = @_;
my $jsondevices = $options{custom}->get_devices();
$self->{devices} = [];
for my $jsondevice (@{$jsondevices}) {
my $device = {
id => $jsondevice->{deviceId},
name => $jsondevice->{deviceName},
description => defined($jsondevice->{description}) ? $jsondevice->{description} : '',
site => defined($jsondevice->{siteName}) ? $jsondevice->{siteName} : '',
group => defined($jsondevice->{groupName}) ? $jsondevice->{groupName} : '',
vendor => defined($jsondevice->{vendorName}) ? $jsondevice->{vendorName} : '',
product => defined($jsondevice->{productName}) ? $jsondevice->{productName} : '',
product_type => defined($jsondevice->{productTypeName}) ? $jsondevice->{productTypeName} : '',
version => defined($jsondevice->{versionName}) ? $jsondevice->{versionName} : ''
};
push @{$self->{devices}}, $device;
$self->{output}->output_add(
long_msg => sprintf(
"[id: %s][name: %s][description: %s][site: %s][group: %s][vendor: %s][product: %s][product_type: %s][version: %s]",
$device->{id},
$device->{name},
$device->{description},
$device->{site},
$device->{group},
$device->{vendor},
$device->{product},
$device->{product_type},
$device->{version}
)
);
}
if (!defined($options{disco_show})) {
$self->{output}->output_add(severity => 'OK', short_msg => 'Devices:');
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
}
}
sub disco_format {
my ($self, %options) = @_;
$self->{output}->add_disco_format(elements => [ 'id', 'name', 'description', 'site', 'group', 'vendor', 'product', 'product_type', 'version' ]);
}
sub disco_show {
my ($self, %options) = @_;
$options{disco_show} = 1;
$self->run(%options);
for my $device (@{$self->{devices}}) {
$self->{output}->add_disco_entry(
id => $device->{id},
name => $device->{name},
description => $device->{description},
site => $device->{site},
group => $device->{group},
vendor => $device->{vendor},
product => $device->{product},
product_type => $device->{product_type},
version => $device->{version}
);
}
}
1;
__END__
=head1 MODE
List devices using the Backbox REST API.
=back
=cut

View File

@ -31,9 +31,11 @@ sub new {
$self->{version} = '1.0';
$self->{modes} = {
'backup' => 'network::backbox::restapi::mode::backup',
'configstatus' => 'network::backbox::restapi::mode::configstatus',
'intellicheck' => 'network::backbox::restapi::mode::intellicheck'
'backup' => 'network::backbox::restapi::mode::backup',
'device-backup' => 'network::backbox::restapi::mode::devicebackup',
'configstatus' => 'network::backbox::restapi::mode::configstatus',
'intellicheck' => 'network::backbox::restapi::mode::intellicheck',
'list-devices' => 'network::backbox::restapi::mode::listdevices'
};
$self->{custom_modes}->{api} = 'network::backbox::restapi::custom::api';

View File

@ -37,6 +37,7 @@ sub new {
'filter-network-id:s' => { name => 'filter_network_id' },
'filter-organization-name:s' => { name => 'filter_organization_name' },
'filter-organization-id:s' => { name => 'filter_organization_id' },
'filter-model:s' => { name => 'filter_model' },
'filter-tags:s' => { name => 'filter_tags' }
});
@ -70,14 +71,16 @@ sub discovery_devices {
my @results;
foreach (values %$devices) {
next if (defined($self->{option_results}->{filter_network_id}) && $self->{option_results}->{filter_network_id} ne '' &&
$_->{networkId} !~ /$self->{option_results}->{filter_network_id}/);
next if (defined($self->{option_results}->{filter_tags}) && $self->{option_results}->{filter_tags} ne '' &&
(!defined($_->{tags}) || $_->{tags} !~ /$self->{option_results}->{filter_tags}/));
next if (defined($self->{option_results}->{filter_organization_id}) && $self->{option_results}->{filter_organization_id} ne '' &&
$_->{orgId} !~ /$self->{option_results}->{filter_organization_id}/);
next if (defined($self->{option_results}->{filter_organization_name}) && $self->{option_results}->{filter_organization_name} ne '' &&
$options{organizations}->{ $_->{orgId} }->{name} !~ /$self->{option_results}->{filter_organization_name}/);
next if ( !centreon::plugins::misc::is_empty($self->{option_results}->{filter_model})
&& $_->{model} !~ /$self->{option_results}->{filter_model}/);
next if ( !centreon::plugins::misc::is_empty($self->{option_results}->{filter_network_id})
&& $_->{networkId} !~ /$self->{option_results}->{filter_network_id}/);
next if ( !centreon::plugins::misc::is_empty($self->{option_results}->{filter_tags})
&& (!defined($_->{tags}) || $_->{tags} !~ /$self->{option_results}->{filter_tags}/));
next if ( !centreon::plugins::misc::is_empty($self->{option_results}->{filter_organization_id})
&& $_->{orgId} !~ /$self->{option_results}->{filter_organization_id}/);
next if ( !centreon::plugins::misc::is_empty($self->{option_results}->{filter_organization_name})
&& $options{organizations}->{ $_->{orgId} }->{name} !~ /$self->{option_results}->{filter_organization_name}/);
my $node = {
name => $_->{name},
@ -200,27 +203,36 @@ Resources discovery.
=item B<--prettify>
Prettify JSON output.
Prettify the JSON output.
=item B<--resource-type>
Choose the type of resources to discover (can be: 'device', 'network').
Define the type of resources to discover (C<device> or C<network>).
=item B<--filter-model>
Define which resources should be discovered based on the resource's model.
This option will be treated as a regular expression.
=item B<--filter-network-id>
Filter by network ID (can be a regexp).
Define which resources should be discovered based on the resource's network ID.
This option will be treated as a regular expression.
=item B<--filter-organization-id>
Filter by organization ID (can be a regexp).
Define which resources should be discovered based on the resource's organization ID.
This option will be treated as a regular expression.
=item B<--filter-organization-name>
Filter by organization name (can be a regexp).
Define which resources should be discovered based on the resource's organization name.
This option will be treated as a regular expression.
=item B<--filter-tags>
Filter by tags (can be a regexp).
Define which resources should be discovered based on the resource's tags.
This option will be treated as a regular expression.
=back

View File

@ -31,8 +31,11 @@ my @labels = (
'network_id',
'network_name',
'device_serial',
'mode',
'status'
'device_mode',
'device_status',
'vpn_type',
'vpn_name',
'vpn_status'
);
sub new {
@ -62,26 +65,46 @@ sub manage_selection {
orgs => [keys %$organizations]
);
my $results = {};
foreach (keys %$devices) {
my $results = [];
foreach my $id (keys %$devices) {
next if (defined($self->{option_results}->{filter_network_id}) && $self->{option_results}->{filter_network_id} ne '' &&
$devices->{$_}->{networkId} !~ /$self->{option_results}->{filter_network_id}/);
$devices->{$id}->{networkId} !~ /$self->{option_results}->{filter_network_id}/);
next if (defined($self->{option_results}->{filter_organization_id}) && $self->{option_results}->{filter_organization_id} ne '' &&
$devices->{$_}->{organizationId} !~ /$self->{option_results}->{filter_organization_id}/);
$devices->{$id}->{organizationId} !~ /$self->{option_results}->{filter_organization_id}/);
my $organization_name = $organizations->{ $devices->{$_}->{organizationId} }->{name};
my $organization_name = $organizations->{ $devices->{$id}->{organizationId} }->{name};
next if (defined($self->{option_results}->{filter_organization_name}) && $self->{option_results}->{filter_organization_name} ne '' &&
$organization_name !~ /$self->{option_results}->{filter_organization_name}/);
$results->{$_} = {
network_id => $devices->{$_}->{networkId},
network_name => $devices->{$_}->{networkName},
device_serial => $devices->{$_}->{deviceSerial},
organization_id => $devices->{$_}->{organizationId},
organization_name => $organization_name,
mode => $devices->{$_}->{vpnMode},
status => $devices->{$_}->{deviceStatus}
};
foreach (@{$devices->{$id}->{merakiVpnPeers}}) {
push @$results, {
network_id => $devices->{$id}->{networkId},
network_name => $devices->{$id}->{networkName},
device_serial => $devices->{$id}->{deviceSerial},
organization_id => $devices->{$id}->{organizationId},
organization_name => $organization_name,
device_mode => $devices->{$id}->{vpnMode},
device_status => $devices->{$id}->{deviceStatus},
vpn_type => 'meraki',
vpn_name => $_->{networkName},
vpn_status => $_->{reachability}
};
}
foreach (@{$devices->{$id}->{thirdPartyVpnPeers}}) {
push @$results, {
network_id => $devices->{$id}->{networkId},
network_name => $devices->{$id}->{networkName},
device_serial => $devices->{$id}->{deviceSerial},
organization_id => $devices->{$id}->{organizationId},
organization_name => $organization_name,
device_mode => $devices->{$id}->{vpnMode},
device_status => $devices->{$id}->{deviceStatus},
vpn_type => 'thirdParty',
vpn_name => $_->{name},
vpn_status => $_->{reachability}
};
}
}
return $results;
@ -91,9 +114,9 @@ sub run {
my ($self, %options) = @_;
my $results = $self->manage_selection(custom => $options{custom});
foreach my $instance (sort keys %$results) {
foreach my $item (@$results) {
$self->{output}->output_add(long_msg =>
join('', map("[$_: " . $results->{$instance}->{$_} . ']', @labels))
join('', map("[$_: " . $item->{$_} . ']', @labels))
);
}
@ -115,9 +138,9 @@ sub disco_show {
my ($self, %options) = @_;
my $results = $self->manage_selection(custom => $options{custom});
foreach (sort keys %$results) {
foreach my $item (@$results) {
$self->{output}->add_disco_entry(
%{$results->{$_}}
%$item
);
}
}

View File

@ -27,22 +27,46 @@ use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
use Digest::MD5 qw(md5_hex);
sub custom_status_output {
sub custom_device_status_output {
my ($self, %options) = @_;
return 'status: ' . $self->{result_values}->{status} . ' [mode: ' . $self->{result_values}->{mode} . ']';
return 'status: ' . $self->{result_values}->{deviceStatus} . ' [mode: ' . $self->{result_values}->{deviceMode} . ']';
}
sub prefix_tunnel_output {
sub custom_vpn_status_output {
my ($self, %options) = @_;
return "vpn tunnel '" . $options{instance_value}->{deviceSerial} . "' ";
return 'status: ' . $self->{result_values}->{vpnStatus};
}
sub prefix_vpn_output {
my ($self, %options) = @_;
return "vpn tunnel '" . $options{instance_value}->{vpnName} . "' [type: " . $options{instance_value}->{vpnType} . "] ";
}
sub prefix_global_output {
my ($self, %options) = @_;
return 'Vpn tunnels ';
return 'Number of VPNS ';
}
sub device_long_output {
my ($self, %options) = @_;
return sprintf(
"checking device '%s'",
$options{instance_value}->{serial}
);
}
sub prefix_device_output {
my ($self, %options) = @_;
return sprintf(
"device '%s' ",
$options{instance_value}->{serial}
);
}
sub set_counters {
@ -50,29 +74,18 @@ sub set_counters {
$self->{maps_counters_type} = [
{ name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', skipped_code => { -10 => 1 } },
{ name => 'tunnels', type => 1, cb_prefix_output => 'prefix_tunnel_output', message_multiple => 'All vpn tunnels are ok' }
{ name => 'devices', type => 3, cb_prefix_output => 'prefix_device_output', cb_long_output => 'device_long_output', indent_long_output => ' ', message_multiple => 'All devices are ok',
group => [
{ name => 'status', type => 0, skipped_code => { -10 => 1 } },
{ name => 'vpns', type => 1, display_long => 1, cb_prefix_output => 'prefix_vpn_output', message_multiple => 'All VPNs are ok', skipped_code => { -10 => 1 } }
]
}
];
$self->{maps_counters}->{global} = [
{ label => 'total-online', nlabel => 'vpn.tunnels.online.count', display_ok => 0, set => {
key_values => [ { name => 'online' }, { name => 'total' } ],
output_template => 'online: %s',
perfdatas => [
{ template => '%s', min => 0, max => 'total' }
]
}
},
{ label => 'total-offline', nlabel => 'vpn.tunnels.offline.count', display_ok => 0, set => {
key_values => [ { name => 'offline' }, { name => 'total' } ],
output_template => 'offline: %s',
perfdatas => [
{ template => '%s', min => 0, max => 'total' }
]
}
},
{ label => 'total-dormant', nlabel => 'vpn.tunnels.dormant.count', display_ok => 0, set => {
key_values => [ { name => 'dormant' }, { name => 'total' } ],
output_template => 'dormant: %s',
{ label => 'total-unreachable', nlabel => 'vpn.tunnels.unreachable.count', display_ok => 0, set => {
key_values => [ { name => 'unreachable' }, { name => 'total' } ],
output_template => 'unreachable: %s',
perfdatas => [
{ template => '%s', min => 0, max => 'total' }
]
@ -80,13 +93,31 @@ sub set_counters {
}
];
$self->{maps_counters}->{tunnels} = [
$self->{maps_counters}->{status} = [
{
label => 'status', type => 2,
critical_default => '%{status} =~ /offline/i',
label => 'device-status',
type => 2,
unknown_default => '%{status} =~ /offline/i',
set => {
key_values => [ { name => 'status' }, { name => 'mode' }, { name => 'deviceSerial' } ],
closure_custom_output => $self->can('custom_status_output'),
key_values => [ { name => 'deviceStatus' }, { name => 'deviceMode' }, { name => 'deviceSerial' } ],
closure_custom_output => $self->can('custom_device_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
$self->{maps_counters}->{vpns} = [
{
label => 'vpn-status',
type => 2,
critical_default => '%{deviceStatus} =~ /online/i and %{vpnStatus} =~ /unreachable/i',
set => {
key_values => [
{ name => 'vpnStatus' }, { name => 'vpnName' }, { name => 'vpnType' },
{ name => 'deviceStatus' }, { name => 'deviceSerial' }
],
closure_custom_output => $self->can('custom_vpn_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
@ -103,7 +134,9 @@ sub new {
'filter-network-name:s' => { name => 'filter_network_name' },
'filter-organization-name:s' => { name => 'filter_organization_name' },
'filter-organization-id:s' => { name => 'filter_organization_id' },
'filter-device-serial:s' => { name => 'filter_device_serial' }
'filter-device-serial:s' => { name => 'filter_device_serial' },
'filter-vpn-type:s' => { name => 'filter_vpn_type' },
'filter-vpn-name:s' => { name => 'filter_vpn_name' }
});
return $self;
@ -114,26 +147,78 @@ sub manage_selection {
my $datas = $options{custom}->get_datas(skipDevices => 1, skipDevicesStatus => 1, skipNetworks => 1);
$self->{global} = { total => 0, online => 0, offline => 0, dormant => 0 };
$self->{tunnels} = {};
$self->{global} = { unreachable => 0 };
$self->{devices} = {};
foreach my $id (keys %{$datas->{vpn_tunnels_status}}) {
next if (defined($self->{option_results}->{filter_network_name}) && $self->{option_results}->{filter_network_name} ne '' &&
$datas->{vpn_tunnels_status}->{$id}->{networkName} !~ /$self->{option_results}->{filter_network_name}/);
next if (defined($self->{option_results}->{filter_device_serial}) && $self->{option_results}->{filter_device_serial} ne '' &&
$id !~ /$self->{option_results}->{filter_device_serial}/);
next if (defined($self->{option_results}->{filter_organization_id}) && $self->{option_results}->{filter_organization_id} ne '' &&
$datas->{vpn_tunnels_status}->{$id}->{organizationId} !~ /$self->{option_results}->{filter_organization_id}/);
next if (defined($self->{option_results}->{filter_organization_name}) && $self->{option_results}->{filter_organization_name} ne '' &&
$datas->{orgs}->{ $datas->{vpn_tunnels_status}->{$id}->{organizationId} }->{name} !~ /$self->{option_results}->{filter_organization_name}/);
$self->{tunnels}->{$id} = {
deviceSerial => $id,
status => $datas->{vpn_tunnels_status}->{$id}->{deviceStatus},
mode => $datas->{vpn_tunnels_status}->{$id}->{vpnMode}
$self->{devices}->{$id} = {
serial => $id,
status => {
deviceSerial => $id,
deviceStatus => $datas->{vpn_tunnels_status}->{$id}->{deviceStatus},
deviceMode => $datas->{vpn_tunnels_status}->{$id}->{vpnMode}
},
vpns => {}
};
$self->{global}->{total}++;
$self->{global}->{ lc($datas->{vpn_tunnels_status}->{$id}->{deviceStatus}) }++
if (defined($self->{global}->{ lc($datas->{vpn_tunnels_status}->{$id}->{deviceStatus}) }));
foreach (@{$datas->{vpn_tunnels_status}->{$id}->{merakiVpnPeers}}) {
my $type = 'meraki';
next if (defined($self->{option_results}->{filter_vpn_type}) && $self->{option_results}->{filter_vpn_type} ne '' &&
$type !~ /$self->{option_results}->{filter_vpn_type}/);
next if (defined($self->{option_results}->{filter_vpn_name}) && $self->{option_results}->{filter_vpn_name} ne '' &&
$_->{networkName} !~ /$self->{option_results}->{filter_vpn_name}/);
$self->{devices}->{$id}->{vpns}->{ $_->{networkName} } = {
deviceSerial => $id,
deviceStatus => $datas->{vpn_tunnels_status}->{$id}->{deviceStatus},
vpnType => $type,
vpnName => $_->{networkName},
vpnStatus => $_->{reachability}
};
$self->{global}->{total}++;
$self->{global}->{ lc($_->{reachability}) }++
if (defined($self->{global}->{ lc($_->{reachability}) }));
}
foreach (@{$datas->{vpn_tunnels_status}->{$id}->{thirdPartyVpnPeers}}) {
my $type = 'thirdParty';
next if (defined($self->{option_results}->{filter_vpn_type}) && $self->{option_results}->{filter_vpn_type} ne '' &&
$type !~ /$self->{option_results}->{filter_vpn_type}/);
next if (defined($self->{option_results}->{filter_vpn_name}) && $self->{option_results}->{filter_vpn_name} ne '' &&
$_->{name} !~ /$self->{option_results}->{filter_vpn_name}/);
$self->{devices}->{$id}->{vpns}->{ $_->{name} } = {
deviceSerial => $id,
deviceStatus => $datas->{vpn_tunnels_status}->{$id}->{deviceStatus},
vpnType => $type,
vpnName => $_->{name},
vpnStatus => $_->{reachability}
};
$self->{global}->{total}++;
$self->{global}->{ lc($_->{reachability}) }++
if (defined($self->{global}->{ lc($_->{reachability}) }));
}
}
# we remove entries if there is a --filter-vpn-[type|name] and no --filter-device-serial
if ((!defined($self->{option_results}->{filter_device_serial}) || $self->{option_results}->{filter_device_serial} eq '') &&
((defined($self->{option_results}->{filter_vpn_type}) && $self->{option_results}->{filter_vpn_type} ne '') ||
(defined($self->{option_results}->{filter_vpn_name}) && $self->{option_results}->{filter_vpn_name} ne ''))
) {
foreach my $id (keys %{$self->{devices}}) {
delete $self->{devices}->{$id} if (scalar(keys %{$self->{devices}->{$id}->{vpns}}) <= 0);
}
}
}
@ -163,25 +248,48 @@ Filter VPN tunnels by organization name (can be a regexp).
Filter VPN tunnels by device serial (can be a regexp).
=item B<--unknown-status>
=item B<--filter-vpn-type>
Define the conditions to match for the status to be UNKNOWN.
You can use the following variables: %{status}, %{deviceSerial}, %{mode}
Filter VPN tunnels by VPN type (can be a regexp).
=item B<--warning-status>
=item B<--filter-vpn-name>
Filter VPN tunnels by VPN name (can be a regexp).
=item B<--unknown-device-status>
Define the conditions to match for the status to be UNKNOWN (default: '%{deviceStatus} =~ /offline/i').
You can use the following variables: %{deviceStatus}, %{deviceSerial}, %{deviceMode}
=item B<--warning-device-status>
Define the conditions to match for the status to be WARNING.
You can use the following variables: %{status}, %{deviceSerial}, %{mode}
You can use the following variables: %{deviceStatus}, %{deviceSerial}, %{deviceMode}
=item B<--critical-status>
=item B<--critical-device-status>
Define the conditions to match for the status to be CRITICAL (default: '%{status} =~ /offline/i').
You can use the following variables: %{status}, %{deviceSerial}, %{mode}
Define the conditions to match for the status to be CRITICAL.
You can use the following variables: %{deviceStatus}, %{deviceSerial}
=item B<--unknown-vpn-status>
Define the conditions to match for the status to be UNKNOWN.
You can use the following variables: %{vpnStatus}, %{vpnName}, %{vpnType}, %{deviceStatus}, %{deviceSerial}
=item B<--warning-vpn-status>
Define the conditions to match for the status to be WARNING.
You can use the following variables: %{vpnStatus}, %{vpnName}, %{vpnType}, %{deviceStatus}, %{deviceSerial}
=item B<--critical-vpn-status>
Define the conditions to match for the status to be CRITICAL (default: '%{deviceStatus} =~ /online/i and %{vpnStatus} =~ /unreachable/i').
You can use the following variables: %{vpnStatus}, %{vpnName}, %{vpnType}, %{deviceStatus}, %{deviceSerial}
=item B<--warning-*> B<--critical-*>
Thresholds.
Can be: 'total-online', 'total-offline', 'total-dormant'.
Can be: 'total-unreachable'.
=back

View File

@ -49,7 +49,7 @@ sub set_counters {
],
}
},
{ label => '1min', set => {
{ label => '15min', set => {
key_values => [ { name => 'load15' } ],
output_template => '%s',
perfdatas => [
@ -104,24 +104,38 @@ __END__
=head1 MODE
Check load-average.
Check average system load.
=over 8
=item B<--filter-counters>
Only display some counters (regexp can be used).
Example: --filter-counters='15min'
Example: C<--filter-counters='15min'>
=item B<--warning-*>
=item B<--warning-1min>
Warning threshold.
Can be: '1min', '5min', '15min'.
Thresholds.
=item B<--critical-*>
=item B<--critical-1min>
Critical threshold.
Can be: '1min', '5min', '15min'.
Thresholds.
=item B<--warning-5min>
Thresholds.
=item B<--critical-5min>
Thresholds.
=item B<--warning-15min>
Thresholds.
=item B<--critical-15min>
Thresholds.
=back

View File

@ -31,13 +31,16 @@ sub new {
$self->{version} = '1.0';
$self->{modes} = {
'cpu' => 'network::hp::procurve::snmp::mode::cpu',
'environment' => 'network::hp::procurve::snmp::mode::environment',
'interfaces' => 'network::hp::procurve::snmp::mode::interfaces',
'list-interfaces' => 'snmp_standard::mode::listinterfaces',
'memory' => 'network::hp::procurve::snmp::mode::memory',
'stack' => 'network::hp::procurve::snmp::mode::stack',
'virtual-chassis' => 'network::hp::procurve::snmp::mode::virtualchassis'
'cpu' => 'network::hp::procurve::snmp::mode::cpu',
'environment' => 'network::hp::procurve::snmp::mode::environment',
'interfaces' => 'network::hp::procurve::snmp::mode::interfaces',
'list-interfaces' => 'snmp_standard::mode::listinterfaces',
'list-spanning-trees' => 'snmp_standard::mode::listspanningtrees',
'memory' => 'network::hp::procurve::snmp::mode::memory',
'spanning-tree' => 'snmp_standard::mode::spanningtree',
'stack' => 'network::hp::procurve::snmp::mode::stack',
'uptime' => 'snmp_standard::mode::uptime',
'virtual-chassis' => 'network::hp::procurve::snmp::mode::virtualchassis'
};
return $self;

View File

@ -18,7 +18,7 @@
# limitations under the License.
#
package network::huawei::snmp::plugin;
package network::huawei::standard::snmp::plugin;
use strict;
use warnings;
@ -30,11 +30,11 @@ sub new {
bless $self, $class;
$self->{modes} = {
'cpu' => 'network::huawei::snmp::mode::cpu',
'hardware' => 'network::huawei::snmp::mode::hardware',
'interfaces' => 'network::huawei::snmp::mode::interfaces',
'cpu' => 'centreon::common::huawei::standard::snmp::mode::cpu',
'hardware' => 'centreon::common::huawei::standard::snmp::mode::hardware',
'interfaces' => 'centreon::common::huawei::standard::snmp::mode::interfaces',
'list-interfaces' => 'snmp_standard::mode::listinterfaces',
'memory' => 'network::huawei::snmp::mode::memory',
'memory' => 'centreon::common::huawei::standard::snmp::mode::memory',
'uptime' => 'snmp_standard::mode::uptime'
};

View File

@ -0,0 +1,412 @@
#
# 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 network::huawei::wlc::snmp::mode::aphealth;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
sub custom_status_output {
my ($self, %options) = @_;
my $msg = 'data link state: ' . $self->{result_values}->{datalinkstate} . ', power-supply: ' . $self->{result_values}->{powersupply};
return $msg;
}
sub prefix_global_output {
my ($self, %options) = @_;
return 'Access points ';
}
sub ap_long_output {
my ($self, %options) = @_;
return "checking access point '" . $options{instance_value}->{display} . "'";
}
sub prefix_ap_output {
my ($self, %options) = @_;
return "access point '" . $options{instance_value}->{display} . "' ";
}
sub custom_uptime_output {
my ($self, %options) = @_;
return sprintf(
'access point %s online time is: %s', $self->{result_values}->{display},
centreon::plugins::misc::change_seconds(value => $self->{result_values}->{onlinetime}, start => 'd')
);
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'ap',
type => 3,
cb_prefix_output => 'prefix_ap_output',
cb_long_output => 'ap_long_output',
indent_long_output => ' ',
message_multiple => 'All access points are ok',
group => [
{ name => 'health', type => 0 }
]
}
];
$self->{maps_counters}->{health} = [
{
label => 'status',
type => 2,
critical_default => '%{powersupply} =~ /insufficient|limited/ || %{datalinkstate} !~ /run/',
warning_default => '%{powersupply} eq "limited"',
set =>
{
key_values =>
[ { name => 'powersupply' }, { name => 'display' }, { name => 'datalinkstate' } ],
closure_custom_output =>
$self->can('custom_status_output'),
closure_custom_perfdata =>
sub {return 0;},
closure_custom_threshold_check =>
\&catalog_status_threshold_ng
}
},
{ label => 'temperature', nlabel => 'ap.temperature.celsius', set => {
key_values => [ { name => 'temperature' }, { name => 'display' } ],
output_template => 'access point temperature: %.2f C',
perfdatas => [
{ template => '%.2f', unit => 'C', label_extra_instance => 1, instance_use => 'display' }
]
}
},
{ label => 'onlinetime', nlabel => 'ap.online.time', set => {
key_values => [ { name => 'onlinetime' }, { name => 'display' } ],
closure_custom_output => $self->can('custom_uptime_output'),
perfdatas => [
{ template => '%d', unit => '', label_extra_instance => 1, instance_use => 'display' }
]
}
},
{ label => 'bootcount-total', nlabel => 'ap.boot.total.count', set => {
key_values => [ { name => 'bootcount_total' }, { name => 'display' } ],
output_template => 'access point bootcount total: %d',
perfdatas => [
{ template => '%d', unit => '', label_extra_instance => 1, instance_use => 'display' }
]
}
},
{ label => 'memory', nlabel => 'ap.memory.used.percentage', set => {
key_values => [ { name => 'memory' }, { name => 'display' } ],
output_template => 'access point memory: %.2f %%',
perfdatas => [
{ template => '%.2f', unit => '%', label_extra_instance => 1, instance_use => 'display' }
]
}
},
{ label => 'cpu', nlabel => 'ap.cpu.used.percentage', set => {
key_values => [ { name => 'cpu' }, { name => 'display' } ],
output_template => 'access point cpu: %.2f%%',
perfdatas => [
{ template => '%.2f', unit => '%', label_extra_instance => 1, instance_use => 'display' }
]
}
},
{ label => 'up-port-speed', nlabel => 'ap.up.port.bitspersecond', set => {
key_values => [ { name => 'up_port_speed' }, { name => 'display' } ],
output_template => 'access point up-Port speed: %s b/s',
perfdatas => [
{ template => '%s', unit => 'b/s', label_extra_instance => 1, instance_use => 'display' }
]
}
},
{ label => 'up-port-packet-err', nlabel => 'ap.up.port.package.error.percentage', set => {
key_values => [ { name => 'up_port_per' }, { name => 'display' } ],
output_template => 'access point up-Port packet errors: %.2f%%',
perfdatas => [
{ template => '%.2f', unit => '', label_extra_instance => 1, instance_use => 'display' }
]
}
},
{ label => 'online-user-num', nlabel => 'ap.online.user.count', set => {
key_values => [ { name => 'online_user_num' }, { name => 'display' } ],
output_template => 'access online user nums: %d',
perfdatas => [
{ template => '%d', unit => '', label_extra_instance => 1, instance_use => 'display' }
]
}
}
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
"filter-name:s" => { name => 'filter_name' },
"filter-address:s" => { name => 'filter_address' },
"filter-group:s" => { name => 'filter_group' }
});
return $self;
}
my $map_power_supply_state = {
1 => 'normal',
2 => 'insufficient',
3 => 'limited',
4 => 'invalid'
};
my $map_data_link_state = {
1 => 'down',
2 => 'run',
3 => 'noneed'
};
my $mapping = {
name => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.4' },# hwWlanApName
address => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.13' }# hwWlanApIpAddress
};
my $mapping_stat = {
runtime => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.18' },# hwWlanApRunTime
group => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.5' },# hwWlanApGroup
temperature => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.43' },# hwWlanApTemperature
onlinetime => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.21' },# hwWlanApOnlineTime
bootcount_total => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.33' },# hwWlanApBootCountTotal
memory => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.40' },# hwWlanApMemoryUseRate
cpu => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.41' },# hwWlanApCPUUseRate
up_port_speed => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.54' },# hwWlanApUpPortSpeed
up_port_per => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.55' },# hwWlanAPUpPortPER
online_user_num => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.44' },# hwWlanApOnlineUserNum
powersupply =>
{ oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.80', map => $map_power_supply_state },# hwWlanAPPowerSupplyState
datalinkstate =>
{ oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.81', map => $map_data_link_state }# hwWlanApDataLinkState
};
sub manage_selection {
my ($self, %options) = @_;
$self->{ap} = {};
my $request = [ { oid => $mapping->{name}->{oid} } ];
push @$request, { oid => $mapping->{group}->{oid} }
if (defined($self->{option_results}->{filter_group}) && $self->{option_results}->{filter_group} ne '');
push @$request, { oid => $mapping->{address}->{oid} }
if (defined($self->{option_results}->{filter_address}) && $self->{option_results}->{filter_address} ne '');
my $snmp_result = $options{snmp}->get_multiple_table(
oids => $request,
return_type => 1,
nothing_quit => 1
);
foreach (sort keys %$snmp_result) {
next if (!/^$mapping->{name}->{oid}\.(.*)/);
my $instance = $1;
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance);
if (!defined($result->{name}) || $result->{name} eq '') {
$self->{output}->output_add(long_msg =>
"skipping WLC '$instance': cannot get a name. please set it.",
debug => 1);
next;
}
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$result->{name} !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(long_msg =>
"skipping '" . $result->{name} . "': no matching name filter.",
debug => 1);
next;
}
if (defined($self->{option_results}->{filter_address}) && $self->{option_results}->{filter_address} ne '' &&
$result->{address} !~ /$self->{option_results}->{filter_address}/) {
$self->{output}->output_add(long_msg =>
"skipping '" . $result->{address} . "': no matching address filter.",
debug => 1);
next;
}
if (defined($self->{option_results}->{filter_group}) && $self->{option_results}->{filter_group} ne '' &&
$result->{group} !~ /$self->{option_results}->{filter_group}/) {
$self->{output}->output_add(long_msg =>
"skipping '" . $result->{group} . "': no matching group filter.",
debug => 1);
next;
}
$self->{ap}->{ $result->{name} } = {
instance => $instance,
display => $result->{name},
health => {
display => $result->{name}
}
};
}
if (scalar(keys %{$self->{ap}}) <= 0) {
$self->{output}->output_add(long_msg => 'no AP associated');
return;
}
$options{snmp}->load(
oids => [ map($_->{oid}, values(%$mapping_stat)) ],
instances => [ map($_->{instance}, values %{$self->{ap}}) ],
instance_regexp => '^(.*)$'
);
$snmp_result = $options{snmp}->get_leef();
foreach (sort keys %{$self->{ap}}) {
my $result = $options{snmp}->map_instance(
mapping => $mapping_stat,
results => $snmp_result,
instance => $self->{ap}->{$_}->{instance}
);
$self->{ap}->{$_}->{health}->{datalinkstate} = $result->{datalinkstate};
$self->{ap}->{$_}->{health}->{powersupply} = $result->{powersupply};
$self->{ap}->{$_}->{health}->{temperature} = $result->{temperature};
$self->{ap}->{$_}->{health}->{onlinetime} = $result->{onlinetime};
$self->{ap}->{$_}->{health}->{bootcount_total} = $result->{bootcount_total};
$self->{ap}->{$_}->{health}->{memory} = $result->{memory};
$self->{ap}->{$_}->{health}->{cpu} = $result->{cpu};
$self->{ap}->{$_}->{health}->{up_port_speed} = $result->{up_port_speed} * 1000;
$self->{ap}->{$_}->{health}->{up_port_per} = $result->{up_port_per};
$self->{ap}->{$_}->{health}->{online_user_num} = $result->{online_user_num};
}
}
1;
__END__
=head1 MODE
Check AP health.
=over 8
=item B<--filter-counters>
Only display some counters (regexp can be used).
Example: --filter-counters='^temperature|onlinetime$'
=item B<--filter-name>
Filter access point name (can be a regexp)
=item B<--filter-address>
Filter access point IP address (can be a regexp).
=item B<--filter-group>
Filter access point group (can be a regexp).
=item B<--warning-status>
Define the conditions to match for the status to be WARNING. (default: '%{powersupply} eq "limited"').
You can use the following variables: %{powersupply}, %{datalinkstate}, %{display}
=item B<--critical-status>
Define the conditions to match for the status to be CRITICAL (default: '%{powersupply} =~ /insufficient|limited/ || %{datalinkstate} !~ /run/').
You can use the following variables: %{powersupply}, %{datalinkstate}, %{display}
=item B<--warning-temperature>
Thresholds.
=item B<--critical-temperature>
Thresholds.
=item B<--warning-onlinetime>
Thresholds.
=item B<--critical-onlinetime>
Thresholds.
=item B<--warning-bootcount-total>
Thresholds.
=item B<--critical-bootcount-total>
Thresholds.
=item B<--warning-memory>
Thresholds.
=item B<--critical-memory>
Thresholds.
=item B<--warning-cpu>
Thresholds.
=item B<--critical-cpu>
Thresholds.
=item B<--warning-up-port-speed>
Thresholds.
=item B<--critical-up-port-speed>
Thresholds.
=item B<--warning-up-port-packet-err>
Thresholds.
=item B<--critical-up-port-packet-err>
Thresholds.
=item B<--warning-online-user-num>
Thresholds.
=item B<--critical-online-user-num>
Thresholds.
=back
=cut

View File

@ -0,0 +1,346 @@
#
# 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 network::huawei::wlc::snmp::mode::apradio;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
sub prefix_global_output {
my ($self, %options) = @_;
return 'Access points ';
}
sub ap_long_output {
my ($self, %options) = @_;
return "checking access point '" . $options{instance_value}->{display} . "'";
}
sub prefix_ap_output {
my ($self, %options) = @_;
return "access point '" . $options{instance_value}->{display} . "' ";
}
sub custom_status_output {
my ($self, %options) = @_;
my $msg = 'run state: ' . $self->{result_values}->{runstate};
return $msg;
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'ap',
type => 3,
cb_prefix_output => 'prefix_ap_output',
cb_long_output => 'ap_long_output',
indent_long_output => ' ',
message_multiple => 'All access points are ok',
group => [
{ name => 'ap_radio', type => 0 }
]
}
];
$self->{maps_counters}->{ap_radio} = [
{
label => 'status',
type => 2,
critical_default => '%{runstate} ne "up"',
set =>
{
key_values =>
[ { name => 'runstate' }, { name => 'display' } ],
closure_custom_output =>
$self->can('custom_status_output'),
closure_custom_perfdata =>
sub {return 0;},
closure_custom_threshold_check =>
\&catalog_status_threshold_ng
}
},
{ label => 'package-error-rate', nlabel => 'ap.radio.packageerror.percentage', set => {
key_values => [ { name => 'package_error_rate' }, { name => 'display' } ],
output_template => 'radio package error rate: %.2f%%',
perfdatas => [
{ template => '%.2f', unit => '%', label_extra_instance => 1, instance_use => 'display' }
]
}
},
{ label => 'noise', nlabel => 'ap.radio.noise.dbm', set => {
key_values => [ { name => 'noise' }, { name => 'display' } ],
output_template => 'radio noise: %d dBm',
perfdatas => [
{ template => '%d', unit => 'dBm', label_extra_instance => 1, instance_use => 'display' }
]
}
},
{ label => 'channel-utilization-rate', nlabel => 'ap.radio.channel.utilization.percentage', set => {
key_values => [ { name => 'channel_utilization_rate' }, { name => 'display' } ],
output_template => 'radio channel utilization rate: %.2f%%',
perfdatas => [
{ template => '%.2f', unit => '%', label_extra_instance => 1, instance_use => 'display' }
]
}
},
{ label => 'channel-interference-rate', nlabel => 'ap.radio.channel.interference.percentage', set => {
key_values => [ { name => 'channel_interference_rate' }, { name => 'display' } ],
output_template => 'radio channel interference rate: %.2f%%',
perfdatas => [
{ template => '%.2f', unit => '%', label_extra_instance => 1, instance_use => 'display' }
]
}
},
{ label => 'receive-rate', nlabel => 'ap.radio.receive.bitspersecond', set => {
key_values => [ { name => 'receive_rate' }, { name => 'display' } ],
output_template => 'radio channel receive rate: %d b/s',
perfdatas => [
{ template => '%d', unit => 'b/s', label_extra_instance => 1, instance_use => 'display' }
]
}
},
{ label => 'send-rate', nlabel => 'ap.radio.send.bitspersecond', set => {
key_values => [ { name => 'send_rate' }, { name => 'display' } ],
output_template => 'radio channel send rate: %d b/s',
perfdatas => [
{ template => '%d', unit => 'b/s', label_extra_instance => 1, instance_use => 'display' }
]
}
}
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
"filter-name:s" => { name => 'filter_name' },
"filter-address:s" => { name => 'filter_address' },
"filter-group:s" => { name => 'filter_group' }
});
return $self;
}
my $map_runstate = {
1 => 'up',
2 => 'down',
255 => 'invalid'
};
my $mapping = {
name => { oid => '.1.3.6.1.4.1.2011.6.139.16.1.2.1.3' },# hwWlanApName
};
my $mapping_stat = {
ap_group => { oid => '.1.3.6.1.4.1.2011.6.139.16.1.2.1.55' },# hwWlanRadioApGroup
runstate => {
oid => '.1.3.6.1.4.1.2011.6.139.16.1.2.1.6', map => $map_runstate
},# hwWlanRadioRunState
package_error_rate => { oid => '.1.3.6.1.4.1.2011.6.139.16.1.2.1.23' },# hwWlanRadioPER
noise => { oid => '.1.3.6.1.4.1.2011.6.139.16.1.2.1.24' },# hwWlanRadioNoise
channel_utilization_rate => { oid => '.1.3.6.1.4.1.2011.6.139.16.1.2.1.25' },# hwWlanRadioChUtilizationRate
channel_interference_rate => { oid => '.1.3.6.1.4.1.2011.6.139.16.1.2.1.29' },# hwWlanRadioChInterferenceRate
receive_rate => { oid => '.1.3.6.1.4.1.2011.6.139.16.1.2.1.32' },# hwWlanRadioRecvRate
send_rate => { oid => '.1.3.6.1.4.1.2011.6.139.16.1.2.1.37' },# hwWlanRadioSendRate
};
sub manage_selection {
my ($self, %options) = @_;
$self->{ap} = {};
my $request = [ { oid => $mapping->{name}->{oid} } ];
push @$request, { oid => $mapping->{ap_group}->{oid} }
if (defined($self->{option_results}->{filter_group}) && $self->{option_results}->{filter_group} ne '');
my $snmp_result = $options{snmp}->get_multiple_table(
oids => $request,
return_type => 1,
nothing_quit => 1
);
foreach (sort keys %$snmp_result) {
next if (!/^$mapping->{name}->{oid}\.(.*)/);
my $instance = $1;
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance);
if (!defined($result->{name}) || $result->{name} eq '') {
$self->{output}->output_add(long_msg =>
"skipping WLC '$instance': cannot get a name. please set it.",
debug =>
1);
next;
}
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$result->{name} !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(long_msg =>
"skipping '" . $result->{name} . "': no matching name filter.",
debug =>
1);
next;
}
if (defined($self->{option_results}->{filter_group}) && $self->{option_results}->{filter_group} ne '' &&
$result->{group} !~ /$self->{option_results}->{filter_group}/) {
$self->{output}->output_add(long_msg =>
"skipping '" . $result->{group} . "': no matching group filter.",
debug =>
1);
next;
}
$self->{ap}->{ $result->{name} } = {
instance => $instance,
display => $result->{name},
ap_radio => {
display => $result->{name}
}
};
}
if (scalar(keys %{$self->{ap}}) <= 0) {
$self->{output}->output_add(long_msg => 'no AP associated');
return;
}
$options{snmp}->load(
oids => [ map($_->{oid}, values(%$mapping_stat)) ],
instances => [ map($_->{instance}, values %{$self->{ap}}) ],
instance_regexp => '^(.*)$'
);
$snmp_result = $options{snmp}->get_leef();
foreach (sort keys %{$self->{ap}}) {
my $result = $options{snmp}->map_instance(
mapping => $mapping_stat,
results => $snmp_result,
instance => $self->{ap}->{$_}->{instance}
);
$self->{ap}->{$_}->{ap_radio}->{runstate} = $result->{runstate};
$self->{ap}->{$_}->{ap_radio}->{package_error_rate} = $result->{package_error_rate};
$self->{ap}->{$_}->{ap_radio}->{noise} = $result->{noise};
$self->{ap}->{$_}->{ap_radio}->{channel_utilization_rate} = $result->{channel_utilization_rate};
$self->{ap}->{$_}->{ap_radio}->{channel_interference_rate} = $result->{channel_interference_rate};
$self->{ap}->{$_}->{ap_radio}->{receive_rate} = $result->{receive_rate} * 1000;
$self->{ap}->{$_}->{ap_radio}->{send_rate} = $result->{send_rate} * 1000;
}
}
1;
__END__
=head1 MODE
Check AP radio status.
=over 8
=item B<--filter-counters>
Only display some counters (regexp can be used).
Example: --filter-counters='^temperature|onlinetime$'
=item B<--filter-name>
Filter access point radio name (can be a regexp)
=item B<--filter-address>
Filter access point radio IP address (can be a regexp).
=item B<--filter-group>
Filter access point group (can be a regexp).
=item B<--warning-status>
Define the conditions to match for the status to be WARNING.
You can use the following variables: %{runstate}, %{display}
=item B<--critical-status>
Define the conditions to match for the status to be CRITICAL (default: '%{runstate} ne "up"').
You can use the following variables: %{runstate}, %{display}
=item B<--warning-package-error-rate>
Thresholds.
=item B<--critical-package-error-rate>
Thresholds.
=item B<--warning-noise>
Thresholds.
=item B<--critical-noise>
Thresholds.
=item B<--warning-channel-utilization-rate>
Thresholds.
=item B<--critical-channel-utilization-rate>
Thresholds.
=item B<--warning-channel-interference-rate>
Thresholds.
=item B<--critical-channel-interference-rate>
Thresholds.
=item B<--warning-receive-rate>
Thresholds.
=item B<--critical-receive-rate>
Thresholds.
=item B<--warning-send-rate>
Thresholds.
=item B<--critical-send-rate>
Thresholds.
=back
=cut

View File

@ -0,0 +1,544 @@
#
# 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 network::huawei::wlc::snmp::mode::apstatus;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
sub custom_status_output {
my ($self, %options) = @_;
my $msg = 'status: ' . $self->{result_values}->{runstate};
return $msg;
}
sub prefix_global_output {
my ($self, %options) = @_;
return 'Access points ';
}
sub ap_long_output {
my ($self, %options) = @_;
return "checking access point '" . $options{instance_value}->{display} . "'";
}
sub prefix_ap_output {
my ($self, %options) = @_;
return "access point '" . $options{instance_value}->{display} . "' ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' },
{ name => 'ap',
type => 3,
cb_prefix_output => 'prefix_ap_output',
cb_long_output => 'ap_long_output',
indent_long_output => ' ',
message_multiple => 'All access points are ok',
group => [
{ name => 'ap_global', type => 0 }
]
}
];
$self->{maps_counters}->{global} = [
{ label => 'total', nlabel => 'accesspoints.total.count', set => {
key_values => [ { name => 'total' } ],
output_template => 'total: %s',
perfdatas => [
{ label => 'total', template => '%s', min => 0 }
]
}
},
{ label => 'total-idle', nlabel => 'accesspoints.idle.count', set => {
key_values => [ { name => 'idle' } ],
output_template => 'idle: %s',
perfdatas => [
{ label => 'total_idle', template => '%s', min => 0 }
]
}
},
{ label => 'total-autofind', nlabel => 'accesspoints.autofind.count', set => {
key_values => [ { name => 'autofind' } ],
output_template => 'autofind: %s',
perfdatas => [
{ label => 'total_autofind', template => '%s', min => 0 }
]
}
},
{ label => 'total-typeNotMatch', nlabel => 'accesspoints.typenotmatch.count', display_ok => 0, set => {
key_values => [ { name => 'typeNotMatch' } ],
output_template => 'type not match: %s',
perfdatas => [
{ label => 'total_type_not_match', template => '%s', min => 0 }
]
}
},
{ label => 'total-fault', nlabel => 'accesspoints.fault.count', set => {
key_values => [ { name => 'fault' } ],
output_template => 'fault: %s',
perfdatas => [
{ label => 'total_fault', template => '%s', min => 0 }
]
}
},
{ label => 'total-config', nlabel => 'accesspoints.config.count', set => {
key_values => [ { name => 'config' } ],
output_template => 'config: %s',
perfdatas => [
{ label => 'total_config', template => '%s', min => 0 }
]
}
},
{ label => 'total-config-failed', nlabel => 'accesspoints.configfailed.count', set => {
key_values => [ { name => 'configFailed' } ],
output_template => 'config failed: %s',
perfdatas => [
{ label => 'total_config_failed', template => '%s', min => 0 }
]
}
},
{ label => 'total-download', nlabel => 'accesspoints.download.count', set => {
key_values => [ { name => 'download' } ],
output_template => 'download: %s',
perfdatas => [
{ label => 'total_download', template => '%s', min => 0 }
]
}
},
{ label => 'total-normal', nlabel => 'accesspoints.normal.count', set => {
key_values => [ { name => 'normal' } ],
output_template => 'normal: %s',
perfdatas => [
{ label => 'total_normal', template => '%s', min => 0 }
]
}
},
{ label => 'total-committing', nlabel => 'accesspoints.committing.count', set => {
key_values => [ { name => 'committing' } ],
output_template => 'committing: %s',
perfdatas => [
{ label => 'total_committing', template => '%s', min => 0 }
]
}
},
{ label => 'total-commit-failed', nlabel => 'accesspoints.commitfailed.count', set => {
key_values => [ { name => 'commitFailed' } ],
output_template => 'commit failed: %s',
perfdatas => [
{ label => 'total_commit_failed', template => '%s', min => 0 }
]
}
},
{ label => 'total-standby', nlabel => 'accesspoints.standby.count', set => {
key_values => [ { name => 'standby' } ],
output_template => 'standby: %s',
perfdatas => [
{ label => 'total_standby', template => '%s', min => 0 }
]
}
},
{ label => 'total-version-mismatch', nlabel => 'accesspoints.vermismatch.count', set => {
key_values => [ { name => 'verMismatch' } ],
output_template => 'version mismatch: %s',
perfdatas => [
{ label => 'total_version_mismatch', template => '%s', min => 0 }
]
}
},
{ label => 'total-name-conflicted', nlabel => 'accesspoints.nameconflicted.count', set => {
key_values => [ { name => 'nameConflicted' } ],
output_template => 'name conflicted: %s',
perfdatas => [
{ label => 'total_name_conflicted', template => '%s', min => 0 }
]
}
},
{ label => 'total-invalid', nlabel => 'accesspoints.invalid.count', set => {
key_values => [ { name => 'invalid' } ],
output_template => 'invalid: %s',
perfdatas => [
{ label => 'total_invalid', template => '%s', min => 0 }
]
}
},
{ label => 'total-country-code-mismatch', nlabel => 'accesspoints.countrycodemismatch.count', set => {
key_values => [ { name => 'countryCodeMismatch' } ],
output_template => 'country code mismatch: %s',
perfdatas => [
{ label => 'total_country_code_mismatch', template => '%s', min => 0 }
]
}
}
];
$self->{maps_counters}->{ap_global} = [
{ label => 'status',
type => 2,
critical_default => '%{runstate} =~ /fault|configFailed|commitFailed|verMismatch|nameConflicted|invalid/',
warning_default => '%{runstate} =~ /countryCodeMismatch|typeNotMatch/',
set =>
{
key_values =>
[ { name => 'runstate' }, { name => 'display' } ],
closure_custom_output =>
$self->can('custom_status_output'),
closure_custom_perfdata =>
sub {return 0;},
closure_custom_threshold_check =>
\&catalog_status_threshold_ng
}
}
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$options{options}->add_options(arguments => {
"filter-name:s" => { name => 'filter_name' },
"filter-address:s" => { name => 'filter_address' },
"filter-group:s" => { name => 'filter_group' }
});
return $self;
}
my $map_run_state = {
1 => 'idle',
2 => 'autofind',
3 => 'typeNotMatch',
4 => 'fault',
5 => 'config',
6 => 'configFailed',
7 => 'download',
8 => 'normal',
9 => 'committing',
10 => 'commitFailed',
11 => 'standby',
12 => 'verMismatch',
13 => 'nameConflicted',
14 => 'invalid',
15 => 'countryCodeMismatch'
};
my $mapping = {
name => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.4' },# hwWlanApName
address => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.13' }# hwWlanApIpAddress
};
my $mapping_stat = {
runtime => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.18' },# hwWlanApRunTime
group => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.5' },# hwWlanApGroup
runstate =>
{ oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.6', map => $map_run_state }# hwWlanApRunState
};
sub manage_selection {
my ($self, %options) = @_;
$self->{ap} = {};
$self->{global} = {
total => 0,
idle => 0,
autofind => 0,
typeNotMatch => 0,
fault => 0,
config => 0,
configFailed => 0,
download => 0,
normal => 0,
committing => 0,
commitFailed => 0,
standby => 0,
verMismatch => 0,
nameConflicted => 0,
invalid => 0,
countryCodeMismatch => 0
};
my $request = [ { oid => $mapping->{name}->{oid} } ];
push @$request, { oid => $mapping->{group}->{oid} }
if (defined($self->{option_results}->{filter_group})
&& $self->{option_results}->{filter_group} ne ''
);
push @$request, { oid => $mapping->{address}->{oid} }
if (defined($self->{option_results}->{filter_address}) && $self->{option_results}->{filter_address} ne '');
my $snmp_result = $options{snmp}->get_multiple_table(
oids => $request,
return_type => 1,
nothing_quit => 1
);
foreach (sort keys %$snmp_result) {
next if (!/^$mapping->{name}->{oid}\.(.*)/);
my $instance = $1;
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance);
if (!defined($result->{name}) || $result->{name} eq '') {
$self->{output}->output_add(
long_msg => "skipping WLC '$instance': cannot get a name. please set it.",
debug => 1
);
next;
}
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$result->{name} !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(
long_msg => "skipping '" . $result->{name} . "': no matching name filter.",
debug => 1
);
next;
}
if (defined($self->{option_results}->{filter_address}) && $self->{option_results}->{filter_address} ne '' &&
$result->{address} !~ /$self->{option_results}->{filter_address}/) {
$self->{output}->output_add(
long_msg => "skipping '" . $result->{address} . "': no matching address filter.",
debug => 1
);
next;
}
if (defined($self->{option_results}->{filter_group}) && $self->{option_results}->{filter_group} ne '' &&
$result->{group} !~ /$self->{option_results}->{filter_group}/) {
$self->{output}->output_add(
long_msg => "skipping '" . $result->{group} . "': no matching group filter.",
debug => 1
);
next;
}
$self->{ap}->{ $result->{name} } = {
instance => $instance,
display => $result->{name},
ap_global => { display => $result->{name} }
};
}
if (scalar(keys %{$self->{ap}}) <= 0) {
$self->{output}->output_add(long_msg => 'no AP associated');
return;
}
$options{snmp}->load(
oids => [ map($_->{oid}, values(%$mapping_stat)) ],
instances => [ map($_->{instance}, values %{$self->{ap}}) ],
instance_regexp => '^(.*)$'
);
$snmp_result = $options{snmp}->get_leef();
foreach (sort keys %{$self->{ap}}) {
my $result = $options{snmp}->map_instance(
mapping => $mapping_stat,
results => $snmp_result,
instance => $self->{ap}->{$_}->{instance});
$self->{global}->{total}++;
$self->{global}->{ $result->{runstate} }++;
$self->{ap}->{$_}->{ap_global}->{runstate} = $result->{runstate};
}
}
1;
__END__
=head1 MODE
Check AP status.
=over 8
=item B<--filter-counters>
Only display some counters (regexp can be used).
Example: C<--filter-counters='^total$|^total-normal$'>
=item B<--filter-name>
Filter access point name (can be a regexp)
=item B<--filter-address>
Filter access point IP address (can be a regexp).
=item B<--filter-group>
Filter access point group (can be a regexp).
=item B<--warning-status>
Define the conditions to match for the status to be WARNING. (default: C<'%{runstate} =~ /countryCodeMismatch|typeNotMatch/'>).
You can use the following variables: C<%{runstate}>, C<%{display}>.
C<%(runstate)> can have one of these values: C<idle>, C<autofind>, C<typeNotMatch>, C<fault>, C<config>, C<configFailed>, C<download>, C<normal>, C<committing>, C<commitFailed>, C<standby>, C<verMismatch>, C<nameConflicted>, C<invalid>, C<countryCodeMismatch>.
=item B<--critical-status>
Define the conditions to match for the status to be CRITICAL. (default: C<'%{runstate} =~ /fault|configFailed|commitFailed|verMismatch|nameConflicted|invalid/'>).
You can use the following variables: C<%{runstate}>, C<%{display}>.
C<%(runstate)> can have one of these values: C<idle>, C<autofind>, C<typeNotMatch>, C<fault>, C<config>, C<configFailed>, C<download>, C<normal>, C<committing>, C<commitFailed>, C<standby>, C<verMismatch>, C<nameConflicted>, C<invalid>, C<countryCodeMismatch>.
=item B<--warning-total>
Thresholds.
=item B<--critical-total>
Thresholds.
=item B<--warning-total-idle>
Thresholds.
=item B<--critical-total-idle>
Thresholds.
=item B<--warning-total-autofind>
Thresholds.
=item B<--critical-total-autofind>
Thresholds.
=item B<--warning-total-typeNotMatch>
Thresholds.
=item B<--critical-total-typeNotMatch>
Thresholds.
=item B<--warning-total-fault>
Thresholds.
=item B<--critical-total-fault>
Thresholds.
=item B<--warning-total-config>
Thresholds.
=item B<--critical-total-config>
Thresholds.
=item B<--warning-total-config-failed>
Thresholds.
=item B<--critical-total-config-failed>
Thresholds.
=item B<--warning-total-download>
Thresholds.
=item B<--critical-total-download>
Thresholds.
=item B<--warning-total-normal>
Thresholds.
=item B<--critical-total-normal>
Thresholds.
=item B<--warning-total-committing>
Thresholds.
=item B<--critical-total-committing>
Thresholds.
=item B<--warning-total-commit-failed>
Thresholds.
=item B<--critical-total-commit-failed>
Thresholds.
=item B<--warning-total-standby>
Thresholds.
=item B<--critical-total-standby>
Thresholds.
=item B<--warning-total-version-mismatch>
Thresholds.
=item B<--critical-total-version-mismatch>
Thresholds.
=item B<--warning-total-name-conflicted>
Thresholds.
=item B<--critical-total-name-conflicted>
Thresholds.
=item B<--warning-total-invalid>
Thresholds.
=item B<--critical-total-invalid>
Thresholds.
=item B<--warning-total-country-code-mismatch>
Thresholds.
=item B<--critical-total-country-code-mismatch>
Thresholds.
=back
=cut

View File

@ -0,0 +1,220 @@
#
# 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 network::huawei::wlc::snmp::mode::listaps;
use base qw(centreon::plugins::mode);
use strict;
use warnings;
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$options{options}->add_options(arguments => {
"filter-name:s" => { name => 'filter_name' },
"filter-address:s" => { name => 'filter_address' },
"filter-group:s" => { name => 'filter_group' }
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
sub manage_selection {
my ($self, %options) = @_;
# Collecting all the relevant informations user may needs when using discovery function for AP in Huawei WLC controllers.
# They had been select with https://support.huawei.com/enterprise/en/doc/EDOC1100306136/680fca71/huawei-wlan-ap-mib as support.
my $mapping = {
name => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.4' },# hwWlanApName
serial => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.2' },# hwWlanApSn
ap_group => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.5' },# hwWlanApGroup
address => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.13' },# hwWlanApIpAddress
software => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.22' },# hwWlanApSysSoftwareDesc
run_time => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.18' },# hwWlanApRunTime
hardware => { oid => '.1.3.6.1.4.1.2011.6.139.13.3.3.1.23' }# hwWlanApSysHardwareDesc
};
# parent oid for all the mapping usage
my $oid_bsnAPEntry = '.1.3.6.1.4.1.2011.6.139.13.3.3';
my $snmp_result = $options{snmp}->get_table(
oid => $oid_bsnAPEntry,
start => $mapping->{serial}->{oid},# First oid of the mapping => here : 2
end => $mapping->{hardware}->{oid}# Last oid of the mapping => here : 23
);
my $results = {};
# Iterate for all oids catch in snmp result above
foreach my $oid (keys %$snmp_result) {
next if ($oid !~ /^$mapping->{serial}->{oid}\.(.*)$/);
my $oid_path = $1;
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $oid_path);
if (!defined($result->{name}) || $result->{name} eq '') {
$self->{output}->output_add(long_msg =>
"skipping WLC '$oid_path': cannot get a name. please set it.",
debug =>
1);
next;
}
if (!defined($result->{address}) || $result->{address} eq '') {
$self->{output}->output_add(long_msg =>
"skipping WLC '$oid_path': cannot get a address. please set it.",
debug =>
1);
next;
}
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$result->{name} !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(long_msg =>
"skipping '" . $result->{name} . "': no matching name filter.",
debug =>
1);
next;
}
if (defined($self->{option_results}->{filter_address}) && $self->{option_results}->{filter_address} ne '' &&
$result->{address} !~ /$self->{option_results}->{filter_address}/) {
$self->{output}->output_add(long_msg =>
"skipping '" . $result->{address} . "': no matching address filter.",
debug =>
1);
next;
}
if (defined($self->{option_results}->{filter_group}) && $self->{option_results}->{filter_group} ne '' &&
$result->{ap_group} !~ /$self->{option_results}->{filter_group}/) {
$self->{output}->output_add(long_msg =>
"skipping '" . $result->{ap_group} . "': no matching group filter.",
debug =>
1);
next;
}
$results->{$oid_path} = {
name => $result->{name},
serial => $result->{serial},
address => $result->{address},
hardware => $result->{hardware},
software => $result->{software},
run_time => $result->{run_time},
ap_group => $result->{ap_group}
};
}
return $results;
}
sub run {
my ($self, %options) = @_;
my $results = $self->manage_selection(snmp => $options{snmp});
foreach my $oid_path (sort keys %$results) {
$self->{output}->output_add(
long_msg => sprintf(
'[oid_path: %s] [name: %s] [serial: %s] [address: %s] [hardware: %s] [software: %s] [run_time: %s] [ap_group: %s]',
$oid_path,
$results->{$oid_path}->{name},
$results->{$oid_path}->{serial},
$results->{$oid_path}->{address},
$results->{$oid_path}->{hardware},
$results->{$oid_path}->{software},
centreon::plugins::misc::change_seconds(value => $results->{$oid_path}->{run_time}),
$results->{$oid_path}->{ap_group}
)
);
}
$self->{output}->output_add(
severity => 'OK',
short_msg => 'List aps'
);
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
$self->{output}->exit();
}
sub disco_format {
my ($self, %options) = @_;
$self->{output}->add_disco_format(elements =>
[ 'name', 'serial', 'address', 'hardware', 'software', 'run_time', 'ap_group' ]);
}
sub disco_show {
my ($self, %options) = @_;
my $results = $self->manage_selection(snmp => $options{snmp});
foreach my $oid_path (sort keys %$results) {
$self->{output}->add_disco_entry(
name =>
$results->{$oid_path}->{name},
serial =>
$results->{$oid_path}->{serial},
address =>
$results->{$oid_path}->{address},
hardware =>
$results->{$oid_path}->{hardware},
software =>
$results->{$oid_path}->{software},
run_time =>
defined($results->{$oid_path}->{run_time}) ?
centreon::plugins::misc::change_seconds(value => $results->{$oid_path}->{run_time}) :
"",
ap_group =>
$results->{$oid_path}->{ap_group}
);
}
}
1;
__END__
=head1 MODE
List wireless name.
=over 8
=item B<--filter-name>
Filter access points by name (can be a regexp).
=item B<--filter-address>
Filter access points by IP address (can be a regexp).
=item B<--filter-group>
Filter access point group (can be a regexp).
=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 network::huawei::wlc::snmp::mode::listradios;
use base qw(centreon::plugins::mode);
use strict;
use warnings;
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$options{options}->add_options(arguments => {
"filter-name:s" => { name => 'filter_name' },
"filter-group:s" => { name => 'filter_group' }
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
my $map_runstate = {
1 => 'up',
2 => 'down',
255 => 'invalid'
};
sub manage_selection {
my ($self, %options) = @_;
# Collecting all the relevant information user may needs when using discovery function for AP in Huawei WLC controllers.
# They had been select with https://support.huawei.com/enterprise/en/doc/EDOC1100306136/680fca71/huawei-wlan-ap-mib as support.
my $mapping = {
name => { oid => '.1.3.6.1.4.1.2011.6.139.16.1.2.1.3' },# hwWlanRadioInfoApName
frequence_type => { oid => '.1.3.6.1.4.1.2011.6.139.16.1.2.1.5' },# hwWlanRadioFreqType
ap_group => { oid => '.1.3.6.1.4.1.2011.6.139.16.1.2.1.55' },# hwWlanRadioApGroup
run_state => { oid => '.1.3.6.1.4.1.2011.6.139.16.1.2.1.6', map => $map_runstate },# hwWlanRadioRunState
description => { oid => '.1.3.6.1.4.1.2011.6.139.16.1.2.1.16' },# hwWlanRadioDescription
};
my $request = [ { oid => $mapping->{name}->{oid} } ];
push @$request, { oid => $mapping->{group}->{oid} }
if (defined($self->{option_results}->{filter_group}) && $self->{option_results}->{filter_group} ne '');
push @$request, { oid => $mapping->{address}->{oid} }
if (defined($self->{option_results}->{filter_address}) && $self->{option_results}->{filter_address} ne '');
my $snmp_result = $options{snmp}->get_multiple_table(
oids => $request,
return_type => 1,
nothing_quit => 1
);
my $results = {};
# Iterate for all oids catch in snmp result above
foreach my $oid (keys %$snmp_result) {
next if ($oid !~ /^$mapping->{name}->{oid}\.(.*)$/);
my $oid_path = $1;
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $oid_path);
if (!defined($result->{name}) || $result->{name} eq '') {
$self->{output}->output_add(long_msg => "skipping WLC '$oid_path': cannot get a name. please set it.", debug => 1);
next;
}
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$result->{name} !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(long_msg => "skipping '" . $result->{name} . "': no matching name filter.", debug => 1);
next;
}
if (defined($self->{option_results}->{filter_group}) && $self->{option_results}->{filter_group} ne '' &&
$result->{ap_group} !~ /$self->{option_results}->{filter_group}/) {
$self->{output}->output_add(long_msg => "skipping '" . $result->{ap_group} . "': no matching group filter.", debug => 1);
next;
}
$self->{ap}->{ $result->{name} } = {
instance => $oid_path,
display => $result->{name},
ap_global => { display => $result->{name} },
interfaces => {}
};
}
$options{snmp}->load(
oids => [ map($_->{oid}, values(%$mapping)) ],
instances => [ map($_->{instance}, values %{$self->{ap}}) ],
instance_regexp => '^(.*)$'
);
$snmp_result = $options{snmp}->get_leef();
foreach (keys %{$self->{ap}}) {
my $result = $options{snmp}->map_instance(mapping =>
$mapping, results =>
$snmp_result,
instance =>
$self->{ap}->{$_}->{instance});
$results->{$self->{ap}->{$_}->{instance}} = {
name => $result->{name},
frequence_type => $result->{frequence_type},
run_state => $result->{run_state},
description => $result->{description},
ap_group => $result->{ap_group}
};
}
return $results;
}
sub run {
my ($self, %options) = @_;
my $results = $self->manage_selection(snmp => $options{snmp});
foreach my $oid_path (sort keys %$results) {
$self->{output}->output_add(
long_msg => sprintf(
'[oid_path: %s] [name: %s] [frequence_type: %s] [run_state: %s] [description: %s] [ap_group: %s]',
$oid_path,
$results->{$oid_path}->{name},
$results->{$oid_path}->{frequence_type},
$results->{$oid_path}->{run_state},
$results->{$oid_path}->{description},
$results->{$oid_path}->{ap_group}
)
);
}
$self->{output}->output_add(
severity => 'OK',
short_msg => 'List aps'
);
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
$self->{output}->exit();
}
sub disco_format {
my ($self, %options) = @_;
$self->{output}->add_disco_format(elements =>
[ 'name', 'frequence_type', 'run_state', 'description', 'ap_group' ]);
}
sub disco_show {
my ($self, %options) = @_;
my $results = $self->manage_selection(snmp => $options{snmp});
foreach my $oid_path (sort keys %$results) {
$self->{output}->add_disco_entry(
name => $results->{$oid_path}->{name},
frequence_type => $results->{$oid_path}->{frequence_type},
run_state => $results->{$oid_path}->{run_state},
description => $results->{$oid_path}->{description},
ap_group => $results->{$oid_path}->{ap_group}
);
}
}
1;
__END__
=head1 MODE
List radios.
=over 8
=item B<--filter-name>
Display AP radios matching the filter.
=item B<--filter-group>
Display AP radios matching the filter.
=back
=cut

View File

@ -0,0 +1,299 @@
#
# 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 network::huawei::wlc::snmp::mode::wlanglobal;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
sub custom_normal_output {
my ($self, %options) = @_;
return sprintf(
'Access Points normal state %s on %s (%.2f%%)',
$self->{result_values}->{normal},
$self->{result_values}->{total},
$self->{result_values}->{normal_prct},
);
}
sub custom_success_auth_user_output {
my ($self, %options) = @_;
return sprintf(
'Access Points user authentications %s on %s (%.2f%%)',
$self->{result_values}->{current_auth_user},
$self->{result_values}->{current_user},
$self->{result_values}->{current_auth_user_prct},
);
}
sub custom_current_auth_user_prct_output {
my ($self, %options) = @_;
return sprintf(
'Access Points user authentications %.2f%% (%s on %s)',
$self->{result_values}->{current_auth_user_prct},
$self->{result_values}->{current_auth_user},
$self->{result_values}->{current_user},
);
}
sub custom_normal_prct_output {
my ($self, %options) = @_;
return sprintf(
'Access Points normal state %.2f%% (%s on %s)',
$self->{result_values}->{normal_prct},
$self->{result_values}->{normal},
$self->{result_values}->{total},
);
}
sub custom_fault_prct_output {
my ($self, %options) = @_;
return sprintf(
'Access Points fault state %.2f%% (%s on %s)',
$self->{result_values}->{fault_prct},
$self->{result_values}->{fault},
$self->{result_values}->{total},
);
}
sub custom_fault_output {
my ($self, %options) = @_;
return sprintf(
'Access Points fault state %s on %s (%.2f%%)',
$self->{result_values}->{fault},
$self->{result_values}->{total},
$self->{result_values}->{fault_prct}
);
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' },
];
$self->{maps_counters}->{global} = [
{ label => 'total', nlabel => 'accesspoints.total.count', display_ok => 0, set => {
key_values => [ { name => 'total' } ],
output_template => 'total: %s',
perfdatas => [
{ template => '%s', min => 0 }
]
}
},
{ label => 'normal', nlabel => 'accesspoints.normal.count', display_ok => 1, set => {
key_values => [ { name => 'normal' }, { name => 'total' }, { name => 'normal_prct' } ],
closure_custom_output => $self->can('custom_normal_output'),
perfdatas => [
{ template => '%s', min => 0 }
]
}
},
{ label => 'fault', nlabel => 'accesspoints.fault.count', display_ok => 0, set => {
key_values => [ { name => 'fault' }, { name => 'total' }, { name => 'fault_prct' } ],
closure_custom_output => $self->can('custom_fault_output'),
perfdatas => [
{ template => '%s', min => 0 }
]
}
},
{ label => 'normal-prct', nlabel => 'accesspoints.normal.percentage', display_ok => 0, set => {
key_values => [ { name => 'normal_prct' }, { name => 'total' }, { name => 'normal' } ],
closure_custom_output => $self->can('custom_normal_output_prct'),
perfdatas => [
{ template => '%.2f', unit => '%', min => 0, max => 100 }
]
}
},
{ label => 'fault-prct', nlabel => 'accesspoints.fault.percentage', display_ok => 0, set => {
key_values => [ { name => 'fault_prct' }, { name => 'total' }, { name => 'fault' } ],
closure_custom_output => $self->can('custom_fault_output_prct'),
perfdatas => [
{ template => '%.2f', unit => '%', min => 0, max => 100 }
]
}
},
{ label => 'current-user', nlabel => 'accesspoints.user.count', display_ok => 0, set => {
key_values => [ { name => 'current_user' } ],
output_template => 'current user: %s',
perfdatas => [
{ template => '%s', min => 0 }
]
}
},
{ label => 'current-auth-user', nlabel => 'accesspoints.user.auth.count', display_ok => 0, set => {
key_values => [ { name => 'current_auth_user' }, { name => 'current_auth_user_prct' }, { name => 'current_user' } ],
closure_custom_output => $self->can('custom_success_auth_user_output'),
perfdatas => [
{ template => '%s', min => 0 }
]
}
},
{ label => 'current-auth-user-prct', nlabel => 'accesspoints.user.auth.percentage', display_ok => 1, set => {
key_values => [ { name => 'current_auth_user_prct' }, { name => 'current_auth_user' }, { name => 'current_user' } ],
closure_custom_output => $self->can('custom_current_auth_user_prct_output'),
perfdatas => [
{ template => '%.2f', unit => '%', min => 0, max => 100 }
]
}
}
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$options{options}->add_options(arguments => {});
return $self;
}
my $oid_normal = '.1.3.6.1.4.1.2011.6.139.12.1.5.6.0';# hwWlanServiceNormalAPCount
my $oid_total = '.1.3.6.1.4.1.2011.6.139.12.1.5.7.0';# hwWlanApCount
my $oid_cur_user = '.1.3.6.1.4.1.2011.6.139.12.1.2.2.0';# hwWlanCurAssocStaNum
my $oid_cur_auth_user = '.1.3.6.1.4.1.2011.6.139.12.1.2.3.0';# hwWlanCurAuthSuccessStaNum
sub manage_selection {
my ($self, %options) = @_;
$self->{global} = {
total => 0,
normal => 0,
normal_prct => 0,
fault => 0,
fault_prct => 0,
current_user => 0,
current_auth_user => 0
};
my $snmp_result = $options{snmp}->get_leef(
oids => [ $oid_normal, $oid_total, $oid_cur_user, $oid_cur_auth_user ],
nothing_quit => 0
);
$self->{global} = {
total => $snmp_result->{$oid_total},
normal => $snmp_result->{$oid_normal},
current_user => $snmp_result->{$oid_cur_user},
current_auth_user => $snmp_result->{$oid_cur_auth_user}
};
$self->{global}->{fault} = $self->{global}->{total} > 0 && $self->{global}->{normal} > 0 ?
$self->{global}->{total} - $self->{global}->{normal} : 0;
$self->{global}->{normal_prct} = $self->{global}->{total} > 0 ?
$self->{global}->{normal} * 100 / $self->{global}->{total} : 0;
$self->{global}->{fault_prct} = $self->{global}->{total} > 0 ?
$self->{global}->{fault} * 100 / $self->{global}->{total} : 0;
$self->{global}->{current_auth_user_prct} = $self->{global}->{current_user} > 0 ?
$self->{global}->{current_auth_user} * 100 / $self->{global}->{current_user} : 0;
}
1;
__END__
=head1 MODE
Check global WLAN access point count and user associated and authenticated.
=over 8
=item B<--warning-total>
Thresholds.
=item B<--critical-total>
Thresholds.
=item B<--warning-normal>
Thresholds.
=item B<--critical-normal>
Thresholds.
=item B<--warning-normal-prct>
Thresholds.
=item B<--critical-normal-prct>
Thresholds.
=item B<--warning-fault>
Thresholds.
=item B<--critical-fault>
Thresholds.
=item B<--warning-fault-prct>
Thresholds.
=item B<--critical-fault-prct>
Thresholds.
=item B<--warning-current-user>
Thresholds.
=item B<--critical-current-user>
Thresholds.
=item B<--warning-current-auth-user>
Thresholds.
=item B<--critical-current-auth-user>
Thresholds.
=item B<--warning-current-auth-user-prct>
Thresholds.
=item B<--critical-current-auth-user-prct>
Thresholds.
=back
=cut

View File

@ -0,0 +1,58 @@
#
# 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 network::huawei::wlc::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} = {
'ap-health' => 'network::huawei::wlc::snmp::mode::aphealth',
'ap-radio' => 'network::huawei::wlc::snmp::mode::apradio',
'ap-status' => 'network::huawei::wlc::snmp::mode::apstatus',
'cpu' => 'centreon::common::huawei::standard::snmp::mode::cpu',
'hardware' => 'centreon::common::huawei::standard::snmp::mode::hardware',
'interfaces' => 'centreon::common::huawei::standard::snmp::mode::interfaces',
'list-aps' => 'network::huawei::wlc::snmp::mode::listaps',
'list-interfaces' => 'snmp_standard::mode::listinterfaces',
'list-radios' => 'network::huawei::wlc::snmp::mode::listradios',
'memory' => 'centreon::common::huawei::standard::snmp::mode::memory',
'uptime' => 'snmp_standard::mode::uptime',
'wlan-global' => 'network::huawei::wlc::snmp::mode::wlanglobal'
};
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check Huawei WLC in SNMP.
=cut

View File

@ -234,7 +234,7 @@ sub set_counters {
label => 'status',
type => 2,
filter => 'add_status',
critical_default => "%{state} eq 'enabled' and %{plugged} eq 'unplugged'", set => {
critical_default => "%{state} eq 'down'", set => {
key_values => [ { name => 'state' }, { name => 'plugged' }, { name => 'real_name' }, { name => 'user_name' } ],
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
@ -344,8 +344,8 @@ sub check_options {
}
}
my $map_state = { 0 => 'disabled', 1 => 'enabled' };
my $map_plugged = { 0 => 'unplugged', 1 => 'plugged' };
my $map_state = { 0 => 'down', 1 => 'up' };
my $map_plugged = { 0 => 'passive', 1 => 'active' };
sub manage_selection {
my ($self, %options) = @_;
@ -444,7 +444,7 @@ You can use the following variables: %{state}, %{plugged}, %{user_name}, %{real_
=item B<--critical-status>
Define the conditions to match for the status to be CRITICAL (default: "%{state} eq 'enabled' and %{plugged} eq 'unplugged'")
Define the conditions to match for the status to be CRITICAL (default: "%{state} eq 'down'")
You can use the following variables: %{state}, %{plugged}, %{user_name}, %{real_name}
=item B<--warning-*> B<--critical-*>

View File

@ -0,0 +1,132 @@
#
# 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 os::freebsd::snmp::mode::storage;
use base qw(snmp_standard::mode::storage);
use strict;
use warnings;
sub default_storage_type {
my ($self, %options) = @_;
return '^(hrStorageFixedDisk|hrStorageNetworkDisk|hrFSBerkeleyFFS|hrFSOther)$';
}
1;
__END__
=head1 MODE
Check storage system.
=over 8
=item B<--warning-usage>
Warning threshold.
=item B<--critical-usage>
Critical threshold.
=item B<--warning-access>
Warning threshold.
=item B<--critical-access>
Critical threshold.
Check if storage is C<readOnly>: C<--critical-access=readOnly>
=item B<--add-access>
Check storage access (C<readOnly>, C<readWrite>).
=item B<--units>
Units of thresholds (default: '%') ('%', 'B').
=item B<--free>
Thresholds are on free space left.
=item B<--storage>
Define the storage filter on IDs (OID indexes, e.g.: 1,2,...). If empty, all storage systems will be monitored.
To filter on storage names, see C<--name>.
=item B<--name>
Allows to use storage name with option C<--storage> instead of storage OID index.
=item B<--regexp>
Allows to use regexp to filter storage (with option C<--name>).
=item B<--regexp-insensitive>
Allows to use regexp non case-sensitive (with C<--regexp>).
=item B<--path-best-match>
Allows to select best path mount point (with C<--name>).
=item B<--reload-cache-time>
Time in minutes before reloading cache file (default: 180).
=item B<--oid-filter>
Choose OID used to filter storage (default: C<hrStorageDescr>) (values: C<hrStorageDescr>, C<hrFSMountPoint>).
=item B<--oid-display>
Choose OID used to display storage (default: C<hrStorageDescr>) (values: C<hrStorageDescr>, C<hrFSMountPoint>).
=item B<--display-transform-src> B<--display-transform-dst>
Modify the storage name displayed by using a regular expression.
Example: adding C<--display-transform-src='dev' --display-transform-dst='run'> will replace all occurrences of C<dev> with C<run>.
=item B<--show-cache>
Display cache storage data.
=item B<--space-reservation>
Some filesystem has space reserved (like ext4 for root).
The value is in percent of total (default: none) (results like 'df' command).
=item B<--filter-duplicate>
Filter duplicate storages (in used size and total size).
=item B<--filter-storage-type>
Filter storage types with a regexp (default: C<'^(hrStorageFixedDisk|hrStorageNetworkDisk|hrFSBerkeleyFFS|hrFSOther)$'>).
C<hrFSOther> is needed when the default file system is ZFS.
=back
=cut

View File

@ -44,7 +44,7 @@ sub new {
'list-storages' => 'snmp_standard::mode::liststorages',
'memory' => 'os::freebsd::snmp::mode::memory',
'processcount' => 'snmp_standard::mode::processcount',
'storage' => 'snmp_standard::mode::storage',
'storage' => 'os::freebsd::snmp::mode::storage',
'swap' => 'snmp_standard::mode::swap',
'time' => 'snmp_standard::mode::ntp',
'tcpcon' => 'snmp_standard::mode::tcpcon',
@ -60,7 +60,7 @@ __END__
=head1 PLUGIN DESCRIPTION
Check Freebsd operating systems in SNMP.
Some modes ('cpu', 'load, 'swap', 'memory') needs 'bsnmp-ucd'.
Check FreeBSD operating systems in SNMP.
Some modes (C<cpu>, C<load>, C<swap>, C<memory>) need C<bsnmp-ucd>.
=cut

View File

@ -138,7 +138,7 @@ of time that this processor was not idle)
=item B<--use-ucd>
Use UCD mib for CPU average.
Use UCD MIB for CPU average.
=item B<--warning-average>

View File

@ -304,7 +304,7 @@ __END__
=head1 MODE
Check read/write I/O disks (bytes per second, IOPs).
Check read/write I/O disks (bytes per second, IOPS).
=over 8
@ -324,11 +324,11 @@ Can be: 'read', 'write', 'read-iops', 'write-iops',
=item B<--device>
Set the device (number expected) example: 1, 2,... (empty means 'check all devices').
Specify the device to be checked (number expected) example: 1, 2,... (empty means 'check all devices').
=item B<--name>
Allows to use device name with option --device instead of devoce oid index.
Allows to use device name with option --device instead of device OID index.
=item B<--regexp>

View File

@ -191,15 +191,15 @@ Critical threshold in percent.
=item B<--diskpath>
Set the disk path (number expected) example: 1, 2,... (empty means 'check all disks path').
Specify the path of the disk you want to check (number expected) example: 1, 2,... (empty means 'check all disks path').
=item B<--name>
Allows to use disk path name with option --diskpath instead of disk path oid index.
Allows to use disk path name with option --diskpath instead of disk path OID index.
=item B<--regexp>
Allows to use regexp to filter diskpath (with option --name).
Allows to use regexp to filter disk path (with option --name).
=item B<--regexp-insensitive>

View File

@ -1694,7 +1694,7 @@ Display traffic perfdata to be compatible with NagVis widget.
=item B<--interface>
Define the interface filter on IDs (OID indexes, e.g.: 1,2,...). If empty, all interfaces will be monitored.
Check only the interfaces with the specified IDs (OID indexes, e.g.: 1,2,...). If empty, all interfaces will be monitored.
To filter on interface names, see --name.
=item B<--name>
@ -1731,7 +1731,7 @@ Force to use 64 bits counters only. Can be used to improve performance.
=item B<--force-counters32>
Force to use 32-bits counters (even with SNMP versions 2c and 3). To use when 64 bits counters are buggy.
Force to use 32-bit counters (even with SNMP versions 2c and 3). To use when 64 bits counters are buggy.
=item B<--reload-cache-time>

View File

@ -211,15 +211,15 @@ Need to enable "includeAllDisks 10%" on snmpd.conf.
=item B<--diskpath>
Set the disk path (number expected) example: 1, 2,... (empty means 'check all disks path').
Specify the path of the disk you want to check (number expected) example: 1, 2,... (empty means 'check all disks path').
=item B<--name>
Allows to use disk path name with option --diskpath instead of disk path oid index.
Allows to use disk path name with option --diskpath instead of disk path OID index.
=item B<--regexp>
Allows to use regexp to filter diskpath (with option --name).
Allows to use regexp to filter disk path (with option --name).
=item B<--regexp-insensitive>

View File

@ -161,7 +161,7 @@ sub run {
$interface_speed = $self->{option_results}->{speed};
}
if (defined($self->{option_results}->{skip_speed0}) && $interface_speed == 0) {
if (defined($self->{option_results}->{skip_speed0}) && ($interface_speed eq '' || $interface_speed == 0)) {
$self->{output}->output_add(long_msg => "skipping interface '" . $display_value . "': interface speed is 0 and option --skip-speed0 is set");
next;
}
@ -395,7 +395,7 @@ __END__
=item B<--interface>
Set the interface (number expected) example: 1,2,... (empty means 'check all interfaces').
Define which interfaces to monitor (number expected). Example: 1,2... (empty means 'check all interfaces').
=item B<--name>
@ -407,39 +407,41 @@ Set interface speed (in Mb).
=item B<--skip-speed0>
Don't display interface with speed 0.
Avoid displaying interfaces with bandwidth/speed equal to 0.
=item B<--filter-status>
Display interfaces matching the filter (example: 'up').
Filter interfaces based on their status using a regular expression (example: 'up|UP').
=item B<--use-adminstatus>
Display interfaces with AdminStatus 'up'.
Display interfaces with C<AdminStatus> 'up'.
=item B<--oid-filter>
Define the OID to be used to filter interfaces (default: ifName) (values: ifDesc, ifAlias, ifName).
Define the OID to be used to filter interfaces (default: C<ifName>).
Available OIDs: C<ifDesc>, C<ifAlias>, C<ifName>).
=item B<--oid-display>
Define the OID that will be used to name the interfaces (default: ifName) (values: ifDesc, ifAlias, ifName).
Define the OID that will be used to name the interfaces (default: ifName).
Available OIDs: C<ifDesc>, C<ifAlias>, C<ifName>).
=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'
Example: adding C<--display-transform-src='eth' --display-transform-dst='ens'> will replace all occurrences of 'eth' with 'ens'
=item B<--add-extra-oid>
Display an OID.
Example: --add-extra-oid='alias,.1.3.6.1.2.1.31.1.1.1.18'
or --add-extra-oid='vlan,.1.3.6.1.2.1.31.19,%{instance}\..*'
Example: C<--add-extra-oid='alias,.1.3.6.1.2.1.31.1.1.1.18'>
or C<--add-extra-oid='vlan,.1.3.6.1.2.1.31.19,%{instance}\..*'>
=item B<--add-mac-address>
Display interface mac address.
Display interfaces MAC addresses.
=back

View File

@ -116,10 +116,14 @@ sub manage_selection {
if ($self->{global}->{lastExecSeconds} == -1 || $self->{global}->{lastExecSeconds} > $lastExecSeconds) {
$self->{global}->{lastExecSeconds} = $lastExecSeconds;
}
} elsif ($snmp_result->{$oid} =~ /Cleaning: phase (\d+) of (\d+) \(([^)]+)\)/) {
$self->{global}->{lastExecHuman} = "running (phase $1 of $2 : $3)";
$self->{global}->{lastExecSeconds} = 0;
}
}
if ($self->{global}->{lastExecSeconds} != -1) {
# If there is a lastExecSeconds set (if above in the looop) and this is not a cleaning running (elsif above)
if ($self->{global}->{lastExecSeconds} > 0 || ($self->{global}->{lastExecSeconds} == 0 && $self->{global}->{lastExecHuman} eq "never")) {
$self->{global}->{lastExecHuman} = centreon::plugins::misc::change_seconds(
value => $self->{global}->{lastExecSeconds}
);

View File

@ -219,7 +219,7 @@ sub new {
sub manage_selection {
my ($self, %options) = @_;
my $aggregates = $options{custom}->request_api(endpoint => '/api/storage/aggregates?fields=*');
my $aggregates = $options{custom}->request_api(endpoint => '/api/storage/aggregates?fields=name,uuid,state,space');
$self->{aggregates} = {};
foreach (@{$aggregates->{records}}) {

View File

@ -195,7 +195,7 @@ sub new {
sub manage_selection {
my ($self, %options) = @_;
my $cluster = $options{custom}->request_api(endpoint => '/api/cluster?fields=*');
my $cluster = $options{custom}->request_api(endpoint => '/api/cluster?fields=name,statistics,metric');
$self->{clusters} = {
$cluster->{name} => {
@ -219,7 +219,7 @@ sub manage_selection {
}
};
my $nodes = $options{custom}->request_api(endpoint => '/api/cluster/nodes?fields=*');
my $nodes = $options{custom}->request_api(endpoint => '/api/cluster/nodes?fields=name,service_processor');
foreach (@{$nodes->{records}}) {
$self->{clusters}->{ $cluster->{name} }->{nodes}->{ $_->{name} } = {
display => $_->{name},
@ -245,7 +245,7 @@ Check cluster.
=item B<--filter-counters>
Only display some counters (regexp can be used).
Example: --filter-counters='node-status'
Example: C<--filter-counters='node-status'>
=item B<--unknown-node-status>
@ -265,9 +265,9 @@ You can use the following variables: %{state}, %{link_status}, %{display}
=item B<--warning-*> B<--critical-*>
Thresholds.
Can be: 'cpu-utilization' (%), 'read' (B/s), 'write' (B/s), 'read-iops', 'write-iops',
'read-latency' (ms), 'write-lantency' (ms), 'other-latency' (ms), 'total-latency' (ms),
'other' (B/s), 'total' (B/s), 'other-iops', 'total-iops'.
Can be: C<cpu-utilization> (%), C<read> (B/s), C<write> (B/s), C<read-iops>, C<write-iops>,
C<read-latency> (ms), C<write-latency> (ms), C<other-latency> (ms), C<total-latency> (ms),
C<other> (B/s), C<total> (B/s), C<other-iops>, C<total-iops>.
=back

View File

@ -43,7 +43,7 @@ sub check {
next if ($self->check_filter(section => 'shelf', instance => $shelf_instance));
foreach my $fru (@{$shelf->{frus}}) {
my $name = $fru->{type} . ':' . $fru->{id};
my $name = $fru->{type} . ':' . (defined($fru->{id}) ? $fru->{id} : '');
if ($fru->{installed} !~ /true|1/i) {
$self->{output}->output_add(

View File

@ -68,7 +68,7 @@ sub new {
sub get_disks {
my ($self, %options) = @_;
return $self->{custom}->request_api(endpoint => '/api/storage/disks?fields=*');
return $self->{custom}->request_api(endpoint => '/api/storage/disks?fields=name,state,serial_number,bay');
}
sub get_shelves {
@ -76,7 +76,7 @@ sub get_shelves {
return if (defined($self->{shelves}));
$self->{shelves} = $self->{custom}->request_api(endpoint => '/api/storage/shelves?fields=*');
$self->{shelves} = $self->{custom}->request_api(endpoint => '/api/storage/shelves?fields=name,state,serial_number,bay,frus');
}
sub save_custom {
@ -96,7 +96,7 @@ Check hardware.
=item B<--component>
Which component to check (default: '.*').
Can be: 'bay', 'disk', 'fru', 'shelf'.
Can be: C<bay>, C<disk>, C<fru>, C<shelf>.
=item B<--filter>
@ -110,7 +110,7 @@ Define the expected status if no components are found (default: critical).
=item B<--threshold-overload>
Use this option to override the status returned by the plugin when the status label matches a regular expression (syntax: section,[instance,]status,regexp).
Example: --threshold-overload='fru,OK,error'
Example: C<--threshold-overload='fru,OK,error'>
=back

View File

@ -44,7 +44,7 @@ sub check_options {
sub manage_selection {
my ($self, %options) = @_;
return $options{custom}->request_api(endpoint => '/api/storage/volumes?fields=*');
return $options{custom}->request_api(endpoint => '/api/storage/volumes?fields=svm,state,name');
}
sub run {

View File

@ -75,7 +75,7 @@ sub new {
sub manage_selection {
my ($self, %options) = @_;
my $luns = $options{custom}->request_api(endpoint => '/api/storage/luns?fields=*');
my $luns = $options{custom}->request_api(endpoint => '/api/storage/luns?fields=name,status');
$self->{luns} = {};
foreach (@{$luns->{records}}) {

Some files were not shown because too many files have changed in this diff Show More