Release 20250200 (#5433)

This commit is contained in:
pkippes 2025-02-07 10:06:50 +01:00 committed by GitHub
commit cfc4b4059f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
91 changed files with 8529 additions and 183 deletions

View File

@ -25,7 +25,7 @@ runs:
merge-multiple: true
- name: Upload the Regrouped Artifact
uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # v4.0.0
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with:
name: ${{ inputs.target_name }}
path: |

View File

@ -77,7 +77,7 @@ runs:
- if: ${{ inputs.stability != 'stable' }}
name: Restore packages from cache
uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ./*.${{ steps.parse-distrib.outputs.package_extension }}
key: ${{ inputs.cache_key }}
@ -177,6 +177,11 @@ runs:
const path = require('path');
const globber = await glob.create('*.${{ steps.parse-distrib.outputs.package_extension }}');
let stableRpmSubdirectory = '';
if ('${{ inputs.stability }}' === 'stable') {
stableRpmSubdirectory = 'RPMS/';
}
const debTargetProps = '${{ inputs.stability }}' == 'testing' ? '--target-props "release_type=${{ inputs.release_type }}"' : '';
for await (const file of globber.globGenerator()) {
@ -188,7 +193,7 @@ runs:
arch = 'x86_64';
}
await exec.exec(
`jf rt upload "${fileName}" "${{ steps.get_repository_stability_path.outputs.repository_stability_path }}/${arch}/${{ inputs.module_name }}/" --flat`
`jf rt upload "${fileName}" "${{ steps.get_repository_stability_path.outputs.repository_stability_path }}/${arch}/${stableRpmSubdirectory}${{ inputs.module_name }}/" --flat`
);
} else if ('${{ steps.parse-distrib.outputs.package_extension }}' === 'deb') {
let arch = 'all';

View File

@ -122,7 +122,7 @@ runs:
done
shell: bash
- uses: actions/cache/save@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ./*.${{ inputs.package_extension }}
key: ${{ inputs.cache_key }}
@ -130,7 +130,7 @@ runs:
# Add to your PR the label upload-artifacts to get packages as artifacts
- if: ${{ contains(github.event.pull_request.labels.*.name, 'upload-artifacts') }}
name: Upload package artifacts
uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with:
name: packages-${{ inputs.distrib }}
path: ./*.${{ inputs.package_extension}}

View File

@ -16,7 +16,7 @@ runs:
steps:
- name: get the cached plugin
uses: actions/cache/restore@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ./*.${{ inputs.package-extension }}
key: ${{ inputs.cache-key }}

View File

@ -10,10 +10,22 @@ baseurl=https://repo.goreleaser.com/yum/
enabled=1
gpgcheck=0' | tee /etc/yum.repos.d/goreleaser.repo
dnf -y install gcc git gettext rpm-build dos2unix python3 epel-release nfpm-2.41.0 openssl-devel jq zstd selinux-policy-devel
dnf -y install gcc git gettext rpm-build dos2unix python3 epel-release nfpm-2.41.0 openssl-devel jq zstd selinux-policy-devel yum-utils
dnf config-manager --set-enabled powertools
dnf -y install perl-App-cpanminus perl-JSON
cpanm App::FatPacker
cpanm File::Copy::Recursive
# For cpan libs
dnf install -y cpio libcurl-devel libssh-devel expat-devel libuuid-devel zeromq-devel libxml2-devel libffi-devel perl-DBI perl-Net-Pcap freetds freetds-devel perl-Module-Build-Tiny
cpanm Module::Build::Tiny
cpanm Module::Install
# Install fpm (ruby 3 is required)
dnf module reset -y ruby
dnf module enable -y ruby:3.1
dnf install -y ruby ruby-devel
gem install fpm
dnf clean all
EOF

View File

@ -10,10 +10,22 @@ baseurl=https://repo.goreleaser.com/yum/
enabled=1
gpgcheck=0' | tee /etc/yum.repos.d/goreleaser.repo
dnf -y install gcc git gettext rpm-build dos2unix python3 epel-release nfpm-2.41.0 openssl-devel jq zstd selinux-policy-devel
dnf -y install gcc git gettext rpm-build dos2unix python3 epel-release nfpm-2.41.0 openssl-devel jq zstd selinux-policy-devel yum-utils
dnf config-manager --set-enabled crb
dnf -y install perl-App-cpanminus perl-JSON
cpanm App::FatPacker
cpanm File::Copy::Recursive
# For cpan libs
dnf install -y cpio libcurl-devel libssh-devel expat-devel libuuid-devel zeromq-devel libxml2-devel libffi-devel perl-DBI perl-Net-Pcap freetds freetds-devel perl-Module-Build-Tiny
cpanm Module::Build::Tiny
cpanm Module::Install
# Install fpm (ruby 3 is required)
dnf module reset -y ruby
dnf module enable -y ruby:3.1
dnf install -y ruby ruby-devel
gem install fpm
dnf clean all
EOF

View File

@ -55,6 +55,8 @@ apt-get install -y \
cpanm Module::Build::Tiny
cpanm Module::Install
cpanm Crypt::OpenSSL::Guess
gem install fpm
echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | tee /etc/apt/sources.list.d/goreleaser.list
@ -64,3 +66,7 @@ apt-get install -y nfpm=2.41.0
apt-get clean
EOF
COPY .github/patch/fpm-deb.rb.diff /tmp/fpm-deb.rb.diff
# Patch to apply fpm fix for debian package generation while waiting for the official fix to be released (https://github.com/jordansissel/fpm/pull/1947).
RUN patch -i /tmp/fpm-deb.rb.diff $(find / -type f -name "deb.rb") && /bin/rm -rf /tmp/fpm-deb.rb.diff

View File

@ -38,7 +38,6 @@ apt-get install -y \
libapp-fatpacker-perl \
libcurl4-openssl-dev \
libczmq-dev \
libczmq-dev\
libfile-copy-recursive-perl \
libjson-perl \
libmodule-build-tiny-perl \
@ -58,7 +57,6 @@ cpanm Crypt::OpenSSL::Guess
gem install fpm
echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | tee /etc/apt/sources.list.d/goreleaser.list
apt-get update
apt-get install -y nfpm=2.41.0
@ -66,3 +64,7 @@ apt-get install -y nfpm=2.41.0
apt-get clean
EOF
COPY .github/patch/fpm-deb.rb.diff /tmp/fpm-deb.rb.diff
# Patch to apply fpm fix for debian package generation while waiting for the official fix to be released (https://github.com/jordansissel/fpm/pull/1947).
RUN patch -i /tmp/fpm-deb.rb.diff $(find / -type f -name "deb.rb") && /bin/rm -rf /tmp/fpm-deb.rb.diff

View File

@ -66,3 +66,7 @@ apt-get install -y nfpm=2.41.0
apt-get clean
EOF
COPY .github/patch/fpm-deb.rb.diff /tmp/fpm-deb.rb.diff
# Patch to apply fpm fix for debian package generation while waiting for the official fix to be released (https://github.com/jordansissel/fpm/pull/1947).
RUN patch -i /tmp/fpm-deb.rb.diff $(find / -type f -name "deb.rb") && /bin/rm -rf /tmp/fpm-deb.rb.diff

View File

@ -102,7 +102,7 @@ jobs:
stability: ${{ needs.get-environment.outputs.stability }}
- name: Save to cache
uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ./*.${{ matrix.package_extension }}
key: ${{ github.sha }}-${{ github.run_id }}-${{ matrix.package_extension }}-${{ matrix.distrib }}

180
.github/workflows/check-status.yml vendored Normal file
View File

@ -0,0 +1,180 @@
name: check-status
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
on:
pull_request:
branches:
- develop
- master
- hotfix-*
- release-*
jobs:
check-status:
runs-on: ubuntu-24.04
steps:
- name: Check workflow statuses and display token usage
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "current rest api rate usage:"
curl -s -H "Accept: application/vnd.github+json" -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/rate_limit | jq .rate
echo ""
echo ""
echo "current graphql rate usage:"
curl -s -H "Accept: application/vnd.github+json" -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/rate_limit | jq .resources.graphql
echo ""
echo ""
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.number }}
with:
script: |
await exec.exec("sleep 20s");
for (let i = 0; i < 120; i++) {
const failure = [];
const cancelled = [];
const pending = [];
const result = await github.rest.checks.listSuitesForRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: "${{ github.head_ref }}"
});
result.data.check_suites.forEach(({ app: { slug }, conclusion, id}) => {
if (slug === 'github-actions') {
if (conclusion === 'failure' || conclusion === 'cancelled') {
failure.push(id);
} else if (conclusion === null) {
pending.push(id);
}
console.log(`check suite ${id} => ${conclusion === null ? 'pending' : conclusion}`);
}
});
if (pending.length === 0) {
core.setFailed("Cannot get pull request check status");
return;
}
if (failure.length > 0) {
let failureMessage = '';
const failedCheckRuns = [];
for await (const suite_id of failure) {
const resultCheckRuns = await github.rest.checks.listForSuite({
owner: context.repo.owner,
repo: context.repo.repo,
check_suite_id: suite_id
});
resultCheckRuns.data.check_runs.forEach(({ conclusion, name, html_url }) => {
if (conclusion === 'failure' || conclusion === 'cancelled') {
failedCheckRuns.push(`<a href="${html_url}">${name} (${conclusion})</a>`);
}
});
}
core.summary.addRaw(`${failedCheckRuns.length} job(s) failed:`, true)
core.summary.addList(failedCheckRuns);
core.summary.write()
if (failedCheckRuns.length > 0) {
core.setFailed(`${failedCheckRuns.length} job(s) failed`);
return;
}
}
if (pending.length === 1) {
core.info("All workflows are ok");
return;
}
core.info(`${pending.length} workflows in progress`);
await exec.exec("sleep 30s");
}
core.setFailed("Timeout: some jobs are still in progress");
get-environment:
if: |
contains(fromJSON('["pull_request", "pull_request_target"]') , github.event_name) &&
(startsWith(github.base_ref, 'release-') || startsWith(github.base_ref, 'hotfix-'))
uses: ./.github/workflows/get-environment.yml
check-cherry-pick:
needs: [get-environment, check-status]
runs-on: ubuntu-24.04
if: |
contains(fromJSON('["pull_request", "pull_request_target"]') , github.event_name) &&
needs.get-environment.outputs.target_stability == 'testing' &&
! contains(needs.get-environment.outputs.labels, 'skip-cherry-pick')
steps:
- name: Check if the PR is a cherry-pick from dev branch
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
env:
LINKED_DEV_BRANCH: develop
with:
script: |
let linkedPrs = [];
let errorMessage = `This pull request is not a cherry-pick from ${process.env.LINKED_DEV_BRANCH} or has no reference to a pull request which has been merged on ${process.env.LINKED_DEV_BRANCH}\n`;
try {
const pull = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number
});
const { title, body } = pull.data;
[title, body].forEach((text) => {
const linkedPrMatches = text.matchAll(/(?:#|\/pull\/)(\d+)/g);
if (linkedPrMatches) {
[...linkedPrMatches].forEach((match) => {
linkedPrs.push(Number(match[1]));
});
}
});
// remove duplicates
linkedPrs = [...new Set(linkedPrs)];
console.log(`Linked pull requests found in PR title and body: ${linkedPrs.join(', ')}`);
} catch (e) {
throw new Error(`Failed to get information of pull request #${context.issue.number}: ${e}`);
}
for await (const prNumber of linkedPrs) {
try {
const pull = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
if (pull.data.base.ref === process.env.LINKED_DEV_BRANCH) {
if (pull.data.state === 'closed' && pull.data.merged === true) {
console.log(`This pull request is a cherry-pick from pull request #${prNumber} on ${process.env.LINKED_DEV_BRANCH}`);
return;
} else {
errorMessage += `This pull request seems to be a cherry-pick from pull request #${prNumber} on ${process.env.LINKED_DEV_BRANCH} but it is not merged yet\n`;
}
} else {
errorMessage += `Pull request #${prNumber} is linked to ${pull.data.base.ref} instead of ${process.env.LINKED_DEV_BRANCH}\n`;
}
} catch (e) {
errorMessage += `Failed to get information on pull request #${prNumber}: ${e}\n`;
}
}
errorMessage += `\nIf you are sure this PR does not need to be a cherry-pick from ${process.env.LINKED_DEV_BRANCH} or must be merged urgently, `;
errorMessage += `open the pull request on ${process.env.LINKED_DEV_BRANCH} and add label "skip-cherry-pick" to the PR and re-run all jobs of workflow check-status\n`;
throw new Error(errorMessage);

View File

@ -77,7 +77,7 @@ jobs:
stability: ${{ needs.get-environment.outputs.stability }}
- name: Upload apt/dnf packages as artifacts if asked
if: ${{ contains(github.event.pull_request.labels.*.name, 'upload-artifacts') }}
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with:
name: vmware-connector-daemon-${{ matrix.distrib }}
path: centreon-plugin*

View File

@ -84,9 +84,9 @@ jobs:
username: ${{ secrets.HARBOR_CENTREON_PUSH_USERNAME }}
password: ${{ secrets.HARBOR_CENTREON_PUSH_TOKEN }}
- uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1
- uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
- uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0
- uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0
with:
file: .github/docker/packaging/Dockerfile.${{ matrix.dockerfile }}
context: .

View File

@ -69,9 +69,9 @@ jobs:
username: ${{ secrets.HARBOR_CENTREON_PUSH_USERNAME }}
password: ${{ secrets.HARBOR_CENTREON_PUSH_TOKEN }}
- uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1
- uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
- uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0
- uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0
with:
file: .github/docker/testing/Dockerfile.testing-plugins-${{ matrix.dockerfile }}
context: .

View File

@ -69,9 +69,9 @@ jobs:
username: ${{ secrets.HARBOR_CENTREON_PUSH_USERNAME }}
password: ${{ secrets.HARBOR_CENTREON_PUSH_TOKEN }}
- uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1
- uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
- uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0
- uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0
with:
file: .github/docker/unit-tests/Dockerfile.unit-tests-${{ matrix.dockerfile }}
context: .

View File

@ -26,6 +26,9 @@ on:
skip_workflow:
description: "if the current workflow should be skipped"
value: ${{ jobs.get-environment.outputs.skip_workflow }}
labels:
description: "list of labels on the PR"
value: ${{ jobs.get-environment.outputs.labels }}
jobs:
get-environment:
@ -38,6 +41,7 @@ jobs:
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 }}
labels: ${{ steps.has_skip_label.outputs.labels }}
steps:
- name: Check if PR has skip label
@ -46,14 +50,17 @@ jobs:
with:
script: |
let hasSkipLabel = false;
let labels = [];
if (${{ contains(fromJSON('["pull_request", "pull_request_target"]') , github.event_name) }} === true) {
try {
const labels = await github.rest.issues.listLabelsOnIssue({
const fetchedLabels = await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number
});
labels.data.forEach(({ name }) => {
fetchedLabels.data.forEach(({ name }) => {
labels.push(name);
if (name === '${{ format('skip-workflow-{0}', github.workflow) }}') {
hasSkipLabel = true;
}
@ -62,6 +69,9 @@ jobs:
core.warning(`failed to list labels: ${e}`);
}
}
core.setOutput('labels', labels);
return hasSkipLabel;
- name: Checkout sources (current branch)
@ -236,24 +246,43 @@ jobs:
- name: Get version
id: get_version
run: |
if [[ "${{ inputs.version_file }}" == "" ]]; then
VERSION=$(date '+%Y%m%d')
elif [[ "${{ inputs.version_file }}" == */*.yaml ]]; then
VERSION=$(grep 'version: ' ${{ inputs.version_file }} | cut -d' ' -f2 | tr -d '"')
else
VERSION=$(grep VERSION ${{ inputs.version_file }} | cut -d "'" -f 2)
fi
echo "version=$(echo $VERSION)" >> $GITHUB_OUTPUT
shell: bash
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
let version = '';
- name: "Get release: 1 for testing / stable, <date>.<commit_sha> for others"
if ('${{ steps.get_stability.outputs.stability }}' === 'testing') {
const branchName = "${{ github.head_ref || github.ref_name }}";
const matches = branchName.match(/^(?:release|hotfix)-(\d{8})$/);
if (matches) {
version = matches[1];
} else {
throw new Error('invalid version');
}
} else if ('${{ steps.get_stability.outputs.stability }}' === 'unstable') {
const currentDate = new Date();
version = `${currentDate.getFullYear()}${("0" + (currentDate.getMonth() + 1)).slice(-2)}${String(currentDate.getDate()).padStart(2, '0')}`;
} else {
const currentDate = new Date();
version = `${currentDate.getFullYear()}${("0" + (currentDate.getMonth() + 1)).slice(-2)}00`;
}
core.setOutput('version', version);
- name: "Get release: 1 for testing / stable, <date> for others"
id: get_release
run: |
RELEASE=$(date '+%H%M%S')
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
let release = '';
echo "release=$RELEASE" >> $GITHUB_OUTPUT
shell: bash
if (${{ contains(fromJSON('["testing", "unstable"]') , steps.get_stability.outputs.stability) }} === true) {
release = "1"
} else {
release = Date.now()
}
core.setOutput('release', release);
- name: "Get release type: hotfix, release or not defined if not a release"
id: get_release_type
@ -276,7 +305,8 @@ 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 }}']
['skip_workflow', '${{ steps.skip_workflow.outputs.result }}'],
['labels', '${{ steps.has_skip_label.outputs.labels }}'],
];
core.summary
.addHeading(`${context.workflow} environment outputs`)

View File

@ -92,6 +92,7 @@ jobs:
- rpm_provides: ""
- version: ""
- spec_file: ""
- no-auto-depends: false
- distrib: el8
package_extension: rpm
image: packaging-plugins-alma8
@ -112,6 +113,10 @@ jobs:
rpm_provides: "perl(FFI::Platypus::Buffer) perl(FFI::Platypus::Memory)"
rpm_dependencies: "perl(Capture::Tiny) perl(FFI::CheckLib) perl(File::Spec::Functions) perl(IPC::Cmd) perl(JSON::PP) perl(List::Util) perl(autodie) perl(constant) perl(parent)"
no-auto-depends: true
- name: "Mojo::IOLoop::Signal"
rpm_dependencies: "perl-Mojolicious"
rpm_provides: "perl(Mojo::IOLoop::Signal)"
no-auto-depends: true
- name: "Net::DHCP"
rpm_provides: "perl(Net::DHCP::Constants) perl(Net::DHCP::Packet)"
- name: "Net::SMTPS"
@ -131,11 +136,6 @@ jobs:
- name: "ZMQ::LibZMQ4"
version: "0.01"
rpm_dependencies: "zeromq"
- name: "Mojo::IOLoop::Signal"
rpm_dependencies: "perl-Mojolicious"
rpm_provides: "perl(Mojo::IOLoop::Signal)"
no-auto-depends: true
name: package ${{ matrix.distrib }} ${{ matrix.name }}
container:
@ -149,35 +149,25 @@ jobs:
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- if: ${{ contains(matrix.build_distribs, matrix.distrib) }}
name: Check if package already exists
id: check-package-existence
run: |
yum install -y yum-utils epel-release git
yum config-manager --set-enabled crb || true # alma 9
yum config-manager --set-enabled powertools || true # alma 8
yum install -y cpanminus rpm-build libcurl-devel libssh-devel expat-devel gcc libuuid-devel zeromq-devel libxml2-devel libffi-devel perl-DBI perl-Net-Pcap freetds freetds-devel perl-Module-Build-Tiny
dnf module reset -y ruby
dnf module enable -y ruby:3.1
dnf install -y ruby ruby-devel
package_info=$(dnf provides 'perl(${{ matrix.name }})' 2>&1 | tr '[:upper:]' '[:lower:]' || true)
do_not_build="false"
if [[ ! $package_info =~ "no matches found" ]]; then
package_version=$(echo $package_info | grep -oP 'perl\(${{ matrix.name }}\) = \K[0-9]+\.[0-9]+')
if [[ -z "${{ matrix.version }}" || "$package_version" == "${{ matrix.version }}" ]]; then
echo "::warning::Package ${{ matrix.name }} already exists in the official ${{ matrix.distrib }} repository with the same version."
do_not_build="true"
else
echo "::warning::Package ${{ matrix.name }} exists in the official ${{ matrix.distrib }} repository with a different version."
do_not_build="false"
fi
fi
echo "do_not_build=$do_not_build" >> $GITHUB_OUTPUT
shell: bash
- if: ${{ contains(matrix.build_distribs, matrix.distrib) }}
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
repository: kduret/fpm
ref: fix-rpm-perl-dependency-name-unchanged
path: fpm
- if: ${{ contains(matrix.build_distribs, matrix.distrib) }}
name: Build and install fpm # waiting https://github.com/jordansissel/fpm/pull/2066
run: |
dnf install -y bsdtar
cd fpm
gem install bundler
bundle install
make install
shell: bash
- if: ${{ contains(matrix.build_distribs, matrix.distrib) && matrix.spec_file == '' }}
- if: ${{ steps.check-package-existence.outputs.do_not_build == 'false' && contains(matrix.build_distribs, matrix.distrib) && matrix.spec_file == '' }}
run: |
if [ -z "${{ matrix.version }}" ]; then
PACKAGE_VERSION=""
@ -205,15 +195,20 @@ jobs:
done
fi
cpanm Module::Build::Tiny
cpanm Module::Install
export SYBASE="/usr"
fpm -s cpan -t ${{ matrix.package_extension }} --rpm-dist ${{ matrix.distrib }} --verbose --cpan-verbose --no-cpan-test$PACKAGE_DEPENDENCIES$PACKAGE_PROVIDES$PACKAGE_VERSION ${{ matrix.name }}
temp_file=$(mktemp)
created_package=$(fpm -s cpan -t ${{ matrix.package_extension }} --rpm-dist ${{ matrix.distrib }} --verbose --cpan-verbose --no-cpan-test$PACKAGE_DEPENDENCIES$PACKAGE_PROVIDES$PACKAGE_VERSION ${{ matrix.name }} | tee "$temp_file" | grep "Created package" | grep -oP '(?<=:path=>").*?(?=")')
# Check package name
if [ -z "$created_package" ]; then
echo "Error: fpm command failed"
exit 1
fi
# Check rpm
rpm2cpio $created_package | cpio -t
shell: bash
- if: ${{ contains(matrix.build_distribs, matrix.distrib) && matrix.spec_file != '' }}
- if: ${{ steps.check-package-existence.outputs.do_not_build == 'false' && contains(matrix.build_distribs, matrix.distrib) && matrix.spec_file != '' }}
run: |
mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
@ -222,7 +217,7 @@ jobs:
cp -r ~/rpmbuild/RPMS/noarch/*.rpm .
shell: bash
- if: ${{ contains(matrix.build_distribs, matrix.distrib) }}
- if: ${{ steps.check-package-existence.outputs.do_not_build == 'false' && contains(matrix.build_distribs, matrix.distrib) }}
name: Replace '::' with - in the feature path
id: package-name
run: |
@ -232,8 +227,8 @@ jobs:
echo "name_with_dash=$name_with_dash" >> $GITHUB_OUTPUT
shell: bash
- if: ${{ contains(matrix.build_distribs, matrix.distrib) }}
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
- if: ${{ steps.check-package-existence.outputs.do_not_build == 'false' && contains(matrix.build_distribs, matrix.distrib) }}
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with:
name: packages-${{ matrix.package_extension }}-${{ matrix.distrib }}-${{ steps.package-name.outputs.name_with_dash }}
path: ./*.${{ matrix.package_extension }}
@ -251,7 +246,7 @@ jobs:
steps:
- name: Merge Artifacts
uses: actions/upload-artifact/merge@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact/merge@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with:
name: packages-rpm-${{ matrix.distrib }}
pattern: packages-rpm-${{ matrix.distrib }}-*
@ -299,7 +294,7 @@ jobs:
- run: rpmsign --addsign ./*.rpm
shell: bash
- uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ./*.rpm
key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
@ -318,7 +313,6 @@ jobs:
name:
[
"ARGV::Struct",
"Authen::SCRAM::Client",
"Config::AWS",
"Convert::EBCDIC",
"Crypt::Blowfish_PP",
@ -338,42 +332,51 @@ jobs:
"Net::FTPSSL",
"Net::HTTPTunnel",
"Net::MQTT::Simple",
"Net::SMTP_auth",
"Paws",
"Statistics::Regression",
"WWW::Selenium",
"XS::Loader",
"ZMQ::Constants",
"ZMQ::LibZMQ4"
]
include:
- runner_name: ubuntu-24.04
- arch: amd64
- build_distribs: "bullseye,bookworm,jammy"
- build_names: "bullseye-amd64,bookworm,jammy"
- deb_dependencies: ""
- rpm_provides: ""
- version: ""
- use_dh_make_perl: "true"
- spec_file: ""
- distrib: bullseye
- build_name: bullseye-amd64
distrib: bullseye
package_extension: deb
image: packaging-plugins-bullseye
- distrib: bookworm
- build_name: bookworm
distrib: bookworm
package_extension: deb
image: packaging-plugins-bookworm
- distrib: jammy
- build_name: jammy
distrib: jammy
package_extension: deb
image: packaging-plugins-jammy
- distrib: bullseye
- build_name: bullseye-arm64
distrib: bullseye
package_extension: deb
image: packaging-plugins-bullseye-arm64
arch: arm64
runner_name: ["self-hosted", "collect-arm64"]
- name: "Crypt::OpenSSL::AES"
use_dh_make_perl: "false"
deb_dependencies: "libexporter-tiny-perl libxs-install-perl"
no-auto-depends: true
build_names: "bullseye-amd64,bookworm,jammy,bullseye-arm64"
- name: "Device::Modbus::RTU::Client"
build_distribs: "bookworm"
build_names: "bookworm"
- name: "Device::Modbus::TCP::Client"
build_distribs: "bookworm"
build_names: "bookworm"
- name: "Digest::SHA1"
build_names: "jammy"
- name: "Net::Amazon::Signature::V4"
build_distribs: ["bullseye", "jammy"]
build_names: ["bullseye-amd64", "jammy"]
- name: "Net::MQTT::Simple"
version: "1.29"
- name: "Paws"
@ -381,12 +384,13 @@ jobs:
deb_dependencies: "libmoose-perl libmoosex-classattribute-perl libjson-maybexs-perl liburl-encode-perl libargv-struct-perl libmoo-perl libtype-tiny-perl libdatastruct-flat-perl libmodule-find-perl libthrowable-perl liburi-template-perl libnet-amazon-signature-v4-perl"
no-auto-depends: true
- name: "Statistics::Regression"
build_distribs: "bullseye"
build_names: "bullseye-amd64"
version: "0.53"
- name: "ZMQ::LibZMQ4"
use_dh_make_perl: "false"
version: "0.01"
deb_dependencies: "libzmq5"
build_names: "bullseye-amd64,bookworm,jammy,bullseye-arm64"
name: package ${{ matrix.distrib }} ${{ matrix.arch }} ${{ matrix.name }}
container:
image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/${{ matrix.image }}:latest
@ -395,43 +399,62 @@ jobs:
password: ${{ secrets.HARBOR_CENTREON_PULL_TOKEN }}
steps:
- if: ${{ contains(matrix.build_distribs, matrix.distrib) }}
- if: ${{ contains(matrix.build_names, matrix.build_name) }}
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- if: ${{ contains(matrix.build_distribs, matrix.distrib) }}
- if: ${{ contains(matrix.build_names, matrix.build_name) }}
name: Parse distrib name
id: parse-distrib
uses: ./.github/actions/parse-distrib
with:
distrib: ${{ matrix.distrib }}
- if: ${{ contains(matrix.build_distribs, matrix.distrib) }}
name: Get package version
id: package-version
- if: ${{ contains(matrix.build_names, matrix.build_name) }}
name: Get package infos
id: package-infos
run: |
apt-get update
apt-get install -y cpanminus
cpan_info=$(cpanm --info ${{ matrix.name }})
if [ -z "${{ matrix.version }}" ]; then
CPAN_PACKAGE_VERSION=$(cpanm --info ${{ matrix.name }} | sed 's/\.tar\.gz$//' | sed 's/.*\-//' | sed 's/v//')
CPAN_PACKAGE_VERSION=$(echo $cpan_info | sed 's/\.tar\.gz$//' | sed 's/.*\-//' | sed 's/v//')
if [[ ! $CPAN_PACKAGE_VERSION =~ ^[0-9]+\.[0-9]+ ]]; then
echo "::error::Invalid version number: ${CPAN_PACKAGE_VERSION}"
exit 1
fi
PACKAGE_VERSION="${CPAN_PACKAGE_VERSION}"
else
PACKAGE_VERSION="${{ matrix.version }}"
fi
echo "package_version=$(echo $PACKAGE_VERSION)" >> $GITHUB_OUTPUT
CPAN_PACKAGE_NAME=$(echo $cpan_info | sed 's/.*\///g' | sed 's/-[0-9\.]*\.tar\.gz//g' | tr '[:upper:]' '[:lower:]')
PACKAGE_NAME="lib$CPAN_PACKAGE_NAME-perl"
echo "package_name=$(echo $PACKAGE_NAME)" >> $GITHUB_OUTPUT
shell: bash
- if: ${{ contains(matrix.build_distribs, matrix.distrib) && matrix.use_dh_make_perl == 'false' }}
- if: ${{ contains(matrix.build_names, matrix.build_name) }}
name: Check if package already exists
id: check-package-existence
run: |
apt-get install -y ruby libcurl4-openssl-dev libssh-dev uuid-dev libczmq-dev
package_info=$(apt-cache policy ${{ steps.package-infos.outputs.package_name }})
if [[ -n $package_info && "${{ steps.package-infos.outputs.package_name }}" =~ "_" ]]; then
package_info=$(apt-cache policy $(echo ${{ steps.package-infos.outputs.package_name }} | sed 's/_//g'))
fi
do_not_build="false"
if [[ -n $package_info ]]; then
candidate_version=$(echo "$package_info" | grep 'Candidate:' | awk '{print $2}')
if [[ "$candidate_version" == "${{ steps.package-infos.outputs.package_version }}"* ]]; then
echo "::warning::Package ${{ steps.package-infos.outputs.package_name }} already exists in the official ${{ matrix.distrib }} repository with the same version."
do_not_build="true"
else
echo "::warning::Package ${{ steps.package-infos.outputs.package_name }} exists in the official ${{ matrix.distrib }} repository with a different version."
do_not_build="false"
fi
fi
echo "do_not_build=$do_not_build" >> $GITHUB_OUTPUT
shell: bash
- if: ${{ steps.check-package-existence.outputs.do_not_build == 'false' && contains(matrix.build_names, matrix.build_name) && matrix.use_dh_make_perl == 'false' }}
run: |
if [ -z "${{ matrix.deb_dependencies }}" ]; then
PACKAGE_DEPENDENCIES=""
else
@ -439,30 +462,35 @@ jobs:
PACKAGE_DEPENDENCIES="$PACKAGE_DEPENDENCIES --depends $PACKAGE_DEPENDENCY"
done
fi
if [ ! -z "${{ matrix.no-auto-depends }}" ]; then
PACKAGE_DEPENDENCIES="$PACKAGE_DEPENDENCIES --no-auto-depends"
fi
cpanm Module::Build::Tiny
cpanm Module::Install
gem install fpm
# Patch to apply fpm fix for debian package generation while waiting for the official fix to be released.
patch -i .github/patch/fpm-deb.rb.diff $(find / -type f -name "deb.rb")
fpm -a native -s cpan -t ${{ matrix.package_extension }} --deb-dist ${{ matrix.distrib }} --iteration ${{ steps.parse-distrib.outputs.package_distrib_name }} --verbose --cpan-verbose --no-cpan-test$PACKAGE_DEPENDENCIES -v ${{ steps.package-version.outputs.package_version }} ${{ matrix.name }}
temp_file=$(mktemp)
created_package=$(fpm -s cpan -t ${{ matrix.package_extension }} --deb-dist ${{ matrix.distrib }} --iteration ${{ steps.parse-distrib.outputs.package_distrib_name }} --verbose --cpan-verbose --no-cpan-test$PACKAGE_DEPENDENCIES -v ${{ steps.package-infos.outputs.package_version }} ${{ matrix.name }} | tee "$temp_file" | grep "Created package" | grep -oP '(?<=:path=>").*?(?=")') || { echo "Error: fpm command failed"; exit 1; }
# Check package name
if [ -z "$created_package" ]; then
echo "Error: fpm command failed"
exit 1
fi
# Check deb
dpkg-deb --contents $created_package || { echo "Error: dpkg-deb failed for package $created_package"; exit 1; }
shell: bash
- if: ${{ contains(matrix.build_distribs, matrix.distrib) && matrix.use_dh_make_perl == 'true' }}
- if: ${{ steps.check-package-existence.outputs.do_not_build == 'false' && contains(matrix.build_names, matrix.build_name) && matrix.use_dh_make_perl == 'true' }}
run: |
apt-get install -y libcurl4-openssl-dev dh-make-perl libssh-dev uuid-dev libczmq-dev libmodule-install-perl libmodule-build-tiny-perl
# module-build-tiny is required for Mojo::IOLoop::Signal build.
DEB_BUILD_OPTIONS="nocheck nodocs notest" dh-make-perl make --dist ${{ matrix.distrib }} --build --version ${{ steps.package-version.outputs.package_version }}${{ steps.parse-distrib.outputs.package_distrib_separator }}${{ steps.parse-distrib.outputs.package_distrib_name }} --cpan ${{ matrix.name }}
temp_file=$(mktemp)
created_package=$(DEB_BUILD_OPTIONS="nocheck nodocs notest" dh-make-perl make --dist ${{ matrix.distrib }} --build --version ${{ steps.package-infos.outputs.package_version }}${{ steps.parse-distrib.outputs.package_distrib_separator }}${{ steps.parse-distrib.outputs.package_distrib_name }} --cpan ${{ matrix.name }} | tee "$temp_file" | grep "building package" | grep -oP "(?<=in '..\/).*.deb(?=')") || { echo "Error: dh-make-perl command failed"; exit 1; }
# Check package name
if [ -z "$created_package" ]; then
echo "Error: fpm command failed"
exit 1
fi
# Check deb
dpkg-deb --contents $created_package || { echo "Error: dpkg-deb failed for package $created_package"; exit 1; }
shell: bash
- if: ${{ contains(matrix.build_distribs, matrix.distrib) }}
- if: ${{ steps.check-package-existence.outputs.do_not_build == 'false' && contains(matrix.build_names, matrix.build_name) }}
name: Replace '::' with - in the feature path
id: package-name
run: |
@ -472,8 +500,8 @@ jobs:
echo "name_with_dash=$name_with_dash" >> $GITHUB_OUTPUT
shell: bash
- if: ${{ contains(matrix.build_distribs, matrix.distrib) }}
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
- if: ${{ steps.check-package-existence.outputs.do_not_build == 'false' && contains(matrix.build_names, matrix.build_name) }}
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with:
name: packages-${{ matrix.package_extension }}-${{ matrix.distrib }}-${{ matrix.arch }}-${{ steps.package-name.outputs.name_with_dash}}
path: ./*.${{ matrix.package_extension }}
@ -491,7 +519,7 @@ jobs:
steps:
- name: Merge Artifacts
uses: actions/upload-artifact/merge@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact/merge@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with:
name: packages-deb-${{ matrix.distrib }}
pattern: packages-deb-${{ matrix.distrib }}-*
@ -519,13 +547,172 @@ jobs:
name: packages-deb-${{ matrix.distrib }}
path: ./
- uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ./*.deb
key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }}
deliver-packages:
test-packages:
needs: [get-environment, sign-rpm, download-and-cache-deb]
strategy:
fail-fast: false
matrix:
include:
- package_extension: rpm
image: almalinux:8
distrib: el8
arch: amd64
runner_name: ubuntu-24.04
- package_extension: rpm
image: almalinux:9
distrib: el9
arch: amd64
runner_name: ubuntu-24.04
- package_extension: deb
image: debian:bullseye
distrib: bullseye
arch: amd64
runner_name: ubuntu-24.04
- package_extension: deb
image: debian:bookworm
distrib: bookworm
arch: amd64
runner_name: ubuntu-24.04
- package_extension: deb
image: ubuntu:jammy
distrib: jammy
arch: amd64
runner_name: ubuntu-24.04
- package_extension: deb
image: debian:bullseye
distrib: bullseye
arch: arm64
runner_name: ["self-hosted", "collect-arm64"]
runs-on: ${{ matrix.runner_name }}
container:
image: ${{ matrix.image }}
name: Test perl CPAN libs packages on ${{ matrix.package_extension }} ${{ matrix.distrib }} ${{ matrix.arch }}
steps:
- if: ${{ matrix.package_extension == 'rpm' }}
name: Install zstd, perl and Centreon repositories
run: |
dnf install -y zstd perl epel-release 'dnf-command(config-manager)'
dnf config-manager --set-enabled powertools || true # alma 8
dnf config-manager --set-enabled crb || true # alma 9
# Import Centreon GPG key
GPG_KEY_URL="https://yum-gpg.centreon.com/RPM-GPG-KEY-CES"
curl -sSL $GPG_KEY_URL -o RPM-GPG-KEY-CES
rpm --import RPM-GPG-KEY-CES
shell: bash
- if: ${{ matrix.package_extension == 'deb' }}
name: Install zstd, perl and Centreon repositories
run: |
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y zstd perl wget gpg apt-utils procps
wget -O- https://apt-key.centreon.com | gpg --dearmor | tee /etc/apt/trusted.gpg.d/centreon.gpg > /dev/null 2>&1
# Avoid apt to clean packages cache directory
rm -f /etc/apt/apt.conf.d/docker-clean
apt-get update
shell: bash
- name: Restore packages from cache
uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
with:
path: ./*.${{ matrix.package_extension }}
key: ${{ github.sha }}-${{ github.run_id }}-${{ matrix.package_extension }}-${{ matrix.distrib }}
fail-on-cache-miss: true
- if: ${{ matrix.package_extension == 'rpm' }}
name: Install packages
run: |
error_log="install_error_${{ matrix.distrib }}_${{ matrix.arch }}.log"
for package in ./*.rpm; do
echo "Installing package: $package"
# List dependencies, and remove version and comparison operators
dependencies=$(rpm -qpR $package | sed 's/ [0-9.-]*\(\s\|$\)/ /g' | sed 's/ [<>!=]*\(\s\|$\)/ /g')
for dependency in $dependencies; do
# Skip non-perl dependencies
if [[ $dependency != perl* ]]; then
continue
else
echo "Check dependency: $dependency"
# Update the dependency name to match the package name
dependency=$(echo $dependency | sed 's/(/-/g' | sed 's/)//g' | sed 's/::/-/g')
fi
# If the dependency has been built in the same workflow, install it
if [[ -n $(find . -maxdepth 1 -regex "\.\/$dependency-[0-9v].*\.rpm") ]]; then
echo "Installing dependency: $dependency"
error_output=$(dnf install -y ./$dependency*.rpm 2>&1) || { echo "$error_output" >> $error_log; echo "Error during installation of the dependency $dependency" >> $error_log; true; }
fi
done
# Install package, then uninstall it with all his dependencies
echo "Package installation..."
error_output=$(dnf install -y $package 2>&1) || { echo "$error_output" >> $error_log; echo "Error during installation of the package $package" >> $error_log; true; }
echo "Package installation done."
echo "Package uninstallation..."
error_output=$(dnf autoremove --setopt=keepcache=True -y $(echo $package | sed 's/_[0-9].*\.rpm//' | sed 's/.\///') 2>&1) || { echo "$error_output" >> $error_log; echo "Error during autoremove of the package $package" >> $error_log; true; }
echo "Package uninstallation done."
done
# If the file error_log exists and is not empty, the workflow is in error
if [[ -s $error_log ]]; then
cat $error_log
exit 1
fi
shell: bash
- if: ${{ matrix.package_extension == 'deb' }}
name: Install packages
run: |
error_log="install_error_${{ matrix.distrib }}_${{ matrix.arch }}.log"
for package in ./*.deb; do
# If the debian package name ends with amd64 or arm64, we only install it if the tested architecture is the same, otherwise we skip it
if [[ $package == *amd64.deb && ${{ matrix.arch }} != "amd64" || $package == *arm64.deb && ${{ matrix.arch }} != "arm64" ]]; then
continue
fi
echo "Installing package: $package"
# List dependencies
dependencies=$(dpkg-deb -I $package | grep Depends | sed 's/Depends: //' | sed 's/,//g' | sed 's/(\(.*\)//g') || { echo "$error_output" >> $error_log; echo "Error while listing dependencies of the package $package" >> $error_log; true; }
for dependency in $dependencies; do
# If the dependency exists in the Debian repository, don't check the local dependencies
dependency_info=$(apt-cache policy $dependency)
if [[ -n $dependency_info ]]; then
echo "Dependency $dependency exists in debian repository."
else
# If the dependency has been built in the same workflow, install it
for dependency_package in $(find . -maxdepth 1 -regex "\.\/${dependency}_[0-9].*all\.deb" -o -regex "\.\/${dependency}_[0-9].*${{ matrix.arch }}\.deb"); do
echo "Installing dependency: $dependency_package"
error_output=$(apt-get install -y ./$dependency_package 2>&1) || { echo "$error_output" >> $error_log; echo "Error during installation of the dependency $dependency" >> $error_log; true; }
done
fi
done
# Install package, then uninstall it with all his dependencies
echo "Package installation..."
error_output=$(apt-get install -y $package 2>&1) || { echo "$error_output" >> $error_log; echo "Error during installation of the package $package" >> $error_log; true; }
echo "Package installation done."
echo "Package uninstallation..."
error_output=$(apt-get autoremove -y --purge $(echo $package | sed 's/_[0-9].*\.deb//' | sed 's/.\///') 2>&1) || { echo "$error_output" >> $error_log; echo "Error during autoremove of the package $package" >> $error_log; true; }
echo "Package uninstallation done."
done
# If the file error_log exists and is not empty, the workflow is in error
if [[ -s $error_log ]]; then
cat $error_log
exit 1
fi
shell: bash
- name: Upload error log
if: failure()
uses: actions/upload-artifact@v4
with:
name: install_error_log_${{ matrix.distrib }}-${{ matrix.arch }}
path: install_error_${{ matrix.distrib }}_${{ matrix.arch }}.log
deliver-packages:
needs: [get-environment, sign-rpm, download-and-cache-deb, test-packages]
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')) &&

View File

@ -137,7 +137,7 @@ jobs:
# set condition to true if artifacts are needed
- if: ${{ false }}
name: Upload package artifacts
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with:
name: packages-${{ matrix.distrib }}-${{ matrix.arch }}
path: ./*.${{ matrix.package_extension}}

View File

@ -63,7 +63,7 @@ jobs:
cp -r ~/rpmbuild/RPMS/x86_64/*.rpm .
shell: bash
- uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ./*.rpm
key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
@ -97,7 +97,7 @@ jobs:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
- uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ./*.rpm
key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
@ -108,7 +108,7 @@ jobs:
- run: rpmsign --addsign ./*.rpm
shell: bash
- uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ./*.rpm
key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
@ -155,7 +155,7 @@ jobs:
DEB_BUILD_OPTIONS="nocheck nodocs notest noautodbgsym" dh-make-perl make --dist ${{ matrix.distrib }} --verbose --build --version 4.0${{ steps.parse-distrib.outputs.package_distrib_separator }}${{ steps.parse-distrib.outputs.package_distrib_name }} perl-filesys-smbclient/
shell: bash
- uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ./*.deb
key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }}

View File

@ -122,7 +122,7 @@ jobs:
# set condition to true if artifacts are needed
- if: ${{ false }}
name: Upload package artifacts
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with:
name: packages-${{ matrix.distrib }}
path: ./*.${{ matrix.package_extension}}

View File

@ -135,7 +135,7 @@ jobs:
# set condition to true if artifacts are needed
- if: ${{ false }}
name: Upload package artifacts
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with:
name: packages-${{ matrix.distrib }}-${{ matrix.arch }}
path: ./*.${{ matrix.package_extension}}

View File

@ -135,7 +135,7 @@ jobs:
# set condition to true if artifacts are needed
- if: ${{ false }}
name: Upload package artifacts
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with:
name: packages-${{ matrix.distrib }}-${{ matrix.arch }}
path: ./*.${{ matrix.package_extension }}

View File

@ -208,7 +208,7 @@ jobs:
rpm_gpg_signing_passphrase: ${{ secrets.RPM_GPG_SIGNING_PASSPHRASE }}
stability: ${{ needs.get-environment.outputs.stability }}
- uses: actions/cache/save@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ./*.${{ matrix.package_extension }}
key: cache-${{ github.sha }}-${{ matrix.package_extension }}-wsman-${{ matrix.distrib }}-${{ matrix.arch }}-${{ github.head_ref || github.ref_name }}

View File

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

View File

@ -57,7 +57,7 @@ jobs:
cp -r ~/rpmbuild/RPMS/x86_64/*.rpm .
shell: bash
- uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ./*.rpm
key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
@ -91,7 +91,7 @@ jobs:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
- uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ./*.rpm
key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
@ -102,12 +102,12 @@ jobs:
- run: rpmsign --addsign ./*.rpm
shell: bash
- uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ./*.rpm
key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
- uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with:
name: packages-${{ matrix.distrib }}
path: ./*.rpm

View File

@ -37,7 +37,7 @@ jobs:
with:
fetch-depth: 0
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
with:
python-version: '3.9'
@ -137,7 +137,7 @@ jobs:
- name: Upload logs as artifacts if tests failed
if: failure()
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with:
name: plugin-installation-${{ matrix.distrib }}
path: ./lastlog.jsonl
@ -157,7 +157,7 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Prepare FatPacker
uses: shogo82148/actions-setup-perl@9c1eca9952ccc07f9ca4a2097b63df93d9d138e9 # v1.31.3
uses: shogo82148/actions-setup-perl@98dfedee230bcf1ee68d5b021931fc8d63f2016e # v1.31.4
with:
perl-version: '5.34'
install-modules-with: cpm
@ -168,7 +168,7 @@ jobs:
COMMIT=$(git log -1 HEAD --pretty=format:%h)
perl .github/scripts/plugins-source.container.pl "${{ needs.get-plugins.outputs.plugins }}" "${{ needs.get-environment.outputs.version }} ($COMMIT)"
- uses: actions/cache/save@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
- uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ./build/
key: fatpacked-plugins-${{ github.sha }}-${{ github.run_id }}
@ -219,7 +219,7 @@ jobs:
- name: Checkout sources
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
- uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ./build/
key: fatpacked-plugins-${{ github.sha }}-${{ github.run_id }}
@ -353,7 +353,7 @@ jobs:
- name: Upload apt/dnf logs as artifacts if tests failed
if: failure()
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with:
name: plugin-installation-${{ matrix.distrib }}
path: /var/log/robot-plugins-installation-tests.log
@ -412,7 +412,7 @@ jobs:
- name: Checkout sources
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
- uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ./build/
key: fatpacked-plugins-${{ github.sha }}-${{ github.run_id }}

View File

@ -30,7 +30,7 @@ jobs:
- added|modified: 'src/**/*.pm'
- name: Install CPAN Libraries
uses: shogo82148/actions-setup-perl@9c1eca9952ccc07f9ca4a2097b63df93d9d138e9 # v1.31.3
uses: shogo82148/actions-setup-perl@98dfedee230bcf1ee68d5b021931fc8d63f2016e # v1.31.4
with:
perl-version: '5.34'
install-modules-with: cpm

2
.gitignore vendored
View File

@ -1,3 +1,5 @@
log.html
output.xml
report.html
.editorconfig
.idea

View File

@ -1,6 +1,13 @@
{
"dependencies": [
"libboolean-perl",
"libbson-perl",
"libdatetime-perl",
"libmongodb-perl"
"libhash-ordered-perl",
"libmongodb-perl",
"libsafe-isa-perl",
"libtype-tiny-perl",
"libuuid-perl",
"libuuid-urandom-perl"
]
}

View File

@ -1,9 +1,9 @@
{
"dependencies": [
"perl(Time::HiRes)",
"perl(DateTime)",
"perl(MongoDB)",
"perl(Hash::Ordered)",
"perl(MongoDB)",
"perl(Time::HiRes)",
"perl(URI::Encode)"
]
}

View File

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

View File

@ -0,0 +1,9 @@
{
"pkg_name": "centreon-plugin-Applications-Haproxy-Web",
"pkg_summary": "Centreon Plugin to monitor HAProxy through JSON web stats page",
"plugin_name": "centreon_haproxy_web.pl",
"files": [
"centreon/plugins/script_custom.pm",
"apps/haproxy/web/"
]
}

View File

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

View File

@ -0,0 +1,4 @@
{
"dependencies": [
]
}

View File

@ -0,0 +1,9 @@
{
"pkg_name": "centreon-plugin-Applications-Podman-Restapi",
"pkg_summary": "Centreon Plugin",
"plugin_name": "centreon_podman_restapi.pl",
"files": [
"centreon/plugins/script_custom.pm",
"apps/podman/restapi/"
]
}

View File

@ -0,0 +1,4 @@
{
"dependencies": [
]
}

View File

@ -1,5 +1,6 @@
{
"dependencies": [
"libsnmp-perl"
"libsnmp-perl",
"libdatetime-format-strptime-perl"
]
}

View File

@ -1,5 +1,6 @@
{
"dependencies": [
"perl(SNMP)"
"perl(SNMP)",
"perl(DateTime::Format::Strptime)"
]
}

View File

@ -0,0 +1,212 @@
#
# Copyright 2025 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::haproxy::web::custom::api;
use strict;
use warnings;
use centreon::plugins::http;
use JSON::XS;
sub new {
my ($class, %options) = @_;
my $self = {};
bless $self, $class;
if (!defined($options{output})) {
print "Class Custom: Need to specify 'output' argument.\n";
exit 3;
}
if (!defined($options{options})) {
$options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument.");
$options{output}->option_exit();
}
if (!defined($options{noptions})) {
$options{options}->add_options(arguments => {
'basic' => { name => 'basic' },
'credentials' => { name => 'credentials' },
'hostname:s' => { name => 'hostname' },
'ntlmv2' => { name => 'ntlmv2' },
'password:s' => { name => 'password' },
'port:s' => { name => 'port' },
'proto:s' => { name => 'proto' },
'timeout:s' => { name => 'timeout' },
'urlpath:s' => { name => 'url_path' },
'username:s' => { name => 'username' },
'critical-http-status:s' => { name => 'critical_http_status' },
'unknown-http-status:s' => { name => 'unknown_http_status' },
'warning-http-status:s' => { name => 'warning_http_status' }
});
}
$options{options}->add_help(package => __PACKAGE__, sections => 'API OPTIONS', once => 1);
$self->{output} = $options{output};
$self->{http} = centreon::plugins::http->new(%options, default_backend => 'curl');
return $self;
}
sub set_options {
my ($self, %options) = @_;
$self->{option_results} = $options{option_results};
}
sub set_defaults {}
sub check_options {
my ($self, %options) = @_;
$self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : undef;
$self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 8404;
$self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'http';
$self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10;
$self->{url_path} = (defined($self->{option_results}->{url_path})) ? $self->{option_results}->{url_path} : '/stats;json;';
$self->{unknown_http_status} = (defined($self->{option_results}->{unknown_http_status})) ? $self->{option_results}->{unknown_http_status} : '(%{http_code} < 200 or %{http_code} >= 300) and %{http_code} != 424';
$self->{warning_http_status} = (defined($self->{option_results}->{warning_http_status})) ? $self->{option_results}->{warning_http_status} : '';
$self->{critical_http_status} = (defined($self->{option_results}->{critical_http_status})) ? $self->{option_results}->{critical_http_status} : '';
if (!defined($self->{hostname}) || $self->{hostname} eq '') {
$self->{output}->add_option_msg(short_msg => "Need to specify --hostname option.");
$self->{output}->option_exit();
}
return 0;
}
sub build_options_for_httplib {
my ($self, %options) = @_;
$self->{option_results}->{hostname} = $self->{hostname};
$self->{option_results}->{timeout} = $self->{timeout};
$self->{option_results}->{port} = $self->{port};
$self->{option_results}->{proto} = $self->{proto};
$self->{option_results}->{timeout} = $self->{timeout};
}
sub settings {
my ($self, %options) = @_;
return if (defined($self->{settings_done}));
$self->build_options_for_httplib();
$self->{http}->add_header(key => 'Accept', value => 'application/json');
$self->{http}->add_header(key => 'Content-Type', value => 'application/json');
$self->{http}->set_options(%{$self->{option_results}});
$self->{settings_done} = 1;
}
sub get_hostname {
my ($self, %options) = @_;
return $self->{hostname};
}
sub get_stats {
my ($self, %options) = @_;
$self->settings();
my $response = $self->{http}->request(method => 'GET', url_path => $self->{url_path});
if (!defined($response) || $response eq '') {
$self->{output}->add_option_msg(short_msg => "API returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']");
$self->{output}->option_exit();
}
my $decoded;
eval {
$decoded = JSON::XS->new->decode($response);
};
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)");
$self->{output}->option_exit();
}
if ($self->{http}->get_code() < 200 || $self->{http}->get_code() >= 300) {
$self->{output}->add_option_msg(short_msg => 'API request error (add --debug option to display returned content)');
$self->{output}->option_exit();
}
return $decoded;
}
1;
__END__
=head1 NAME
HAProxy HTTP custom mode for web json stats
=head1 API OPTIONS
HAProxy web stats
=over 8
=item B<--hostname>
IP address or FQDN of the HAProxy server.
=item B<--port>
Port used by the web server
=item B<--proto>
Specify https if needed (default: 'http')
=item B<--urlpath>
Define the path of the web page to get (default: '/stats;json;').
=item B<--credentials>
Specify this option if you are accessing a web page using authentication.
=item B<--username>
Specify the username for authentication (mandatory if --credentials is specified).
=item B<--password>
Specify the password for authentication (mandatory if --credentials is specified).
=item B<--basic>
Specify this option if you are accessing a web page using basic authentication and don't want a '401 UNAUTHORIZED' error to be logged on your web server.
Specify this option if you are accessing a web page using hidden basic authentication or you'll get a '404 NOT FOUND' error.
(use with --credentials)
=item B<--ntlmv2>
Specify this option if you are accessing a web page using NTLMv2 authentication (use with C<--credentials> and C<--port> options).
=item B<--timeout>
Define the timeout in seconds (default: 5).
=back
=cut

View File

@ -0,0 +1,505 @@
#
# Copyright 2025 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::haproxy::web::mode::backendusage;
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_ng);
sub prefix_backend_output {
my ($self, %options) = @_;
return "Backend '" . $options{instance_value}->{display} . "' ";
}
sub prefix_server_output {
my ($self, %options) = @_;
return "Server '" . $options{instance_value}->{svname} . "' ";
}
sub prefix_global_backend_output {
my ($self, %options) = @_;
return 'backend ';
}
sub backend_long_output {
my ($self, %options) = @_;
return "Backend '" . $options{instance_value}->{display} . "':";
}
sub custom_status_output {
my ($self, %options) = @_;
return sprintf("status: %s", $self->{result_values}->{status});
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{
name => 'backends',
type => 3,
cb_prefix_output => 'prefix_backend_output',
cb_long_output => 'backend_long_output',
message_multiple => 'All Backends are ok',
indent_long_output => ' ',
skipped_code => { -10 => 1 },
group => [
{
name => 'backend',
type => 0,
cb_prefix_output => 'prefix_global_backend_output'
},
{
name => 'servers',
type => 1,
display_long => 1,
cb_prefix_output => 'prefix_server_output',
message_multiple => 'Servers are ok',
skipped_code => { -10 => 1 }
}
]
}
];
$self->{maps_counters}->{backend} = [
{
label => 'backend-status',
type => 2,
critical_default => '%{status} !~ /UP/i',
set => {
key_values => [ { name => 'status' }, { name => 'pxname' } ],
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
},
{ label => 'backend-current-queue', nlabel => 'backend.queue.current.count', set => {
key_values => [ { name => 'qcur' }, { name => 'pxname' } ],
output_template => 'current queue: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'backend-current-session-rate', nlabel => 'backend.session.current.rate.countpersecond', set => {
key_values => [ { name => 'rate' }, { name => 'pxname' } ],
output_template => 'current session rate: %s/s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'backend-max-session-rate', nlabel => 'backend.session.max.rate.countpersecond', set => {
key_values => [ { name => 'rate_max' }, { name => 'pxname' } ],
output_template => 'max session rate: %s/s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'backend-current-sessions', nlabel => 'backend.sessions.current.count', set => {
key_values => [ { name => 'scur' }, { name => 'pxname' } ],
output_template => 'current sessions: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'backend-total-sessions', nlabel => 'backend.sessions.total.count', set => {
key_values => [ { name => 'stot', diff => 1 }, { name => 'pxname' } ],
output_template => 'total sessions: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'backend-traffic-in', nlabel => 'backend.traffic.in.bitpersecond', set => {
key_values => [ { name => 'bin', per_second => 1 }, { name => 'pxname' } ],
output_template => 'traffic in: %s %s/s',
output_change_bytes => 2,
perfdatas => [
{ template => '%.2f', min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'backend-traffic-out', nlabel => 'backend.traffic.out.bitpersecond', set => {
key_values => [ { name => 'bout', per_second => 1 }, { name => 'pxname' } ],
output_template => 'traffic out: %s %s/s',
output_change_bytes => 2,
perfdatas => [
{ template => '%.2f', min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'backend-denied-requests', nlabel => 'backend.requests.denied.count', set => {
key_values => [ { name => 'dreq' }, { name => 'pxname' } ],
output_template => 'denied requests: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'backend-denied-responses', nlabel => 'backend.responses.denied.count', set => {
key_values => [ { name => 'dresp' }, { name => 'pxname' } ],
output_template => 'denied responses: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'backend-connections-errors', nlabel => 'backend.connections.error.count', set => {
key_values => [ { name => 'econ' }, { name => 'pxname' } ],
output_template => 'connection errors: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'backend-responses-errors', nlabel => 'backend.responses.error.count', set => {
key_values => [ { name => 'eresp' }, { name => 'pxname' } ],
output_template => 'responses errors: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'pxname' }
]
}
}
];
$self->{maps_counters}->{servers} = [
{
label => 'server-status',
type => 2,
critical_default => '%{status} !~ /UP/i',
set => {
key_values => [ { name => 'status' }, { name => 'svname' } ],
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
},
{ label => 'server-current-sessions', nlabel => 'server.sessions.current.count', set => {
key_values => [ { name => 'scur' }, { name => 'svname' } ],
output_template => 'current sessions: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'svname'}
]
}
},
{ label => 'server-current-session-rate', nlabel => 'server.session.current.rate.countpersecond', set => {
key_values => [ { name => 'rate' }, { name => 'svname' } ],
output_template => 'current session rate: %s/s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'svname' }
]
}
},
{ label => 'server-max-session-rate', nlabel => 'server.session.max.rate.countpersecond', set => {
key_values => [ { name => 'rate_max' }, { name => 'svname' } ],
output_template => 'max session rate: %s/s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'svname' }
]
}
},
{ label => 'server-denied-responses', nlabel => 'server.responses.denied.count', set => {
key_values => [ { name => 'dresp' }, { name => 'svname' } ],
output_template => 'denied responses: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'svname' }
]
}
},
{ label => 'server-connections-errors', nlabel => 'server.connections.error.count', set => {
key_values => [ { name => 'econ' }, { name => 'svname' } ],
output_template => 'connection errors: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'svname' }
]
}
},
{ label => 'server-responses-errors', nlabel => 'server.responses.error.count', set => {
key_values => [ { name => 'eresp' }, { name => 'svname' } ],
output_template => 'responses errors: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'svname' }
]
}
}
];
}
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 => {
'add-servers' => { name => 'add_servers' },
'filter-name:s' => { name => 'filter_name' }
});
return $self;
}
sub manage_selection {
my ($self, %options) = @_;
my $result = $options{custom}->get_stats();
my $stats;
foreach (@$result) {
foreach my $entry (@$_) {
if ($entry->{objType} eq 'Backend') {
$stats->{$entry->{proxyId}}->{$entry->{field}->{name}} = $entry->{value}->{value};
}
if ($entry->{objType} eq 'Server') {
$stats->{$entry->{proxyId}}->{servers}->{$entry->{id}}->{$entry->{field}->{name}} = $entry->{value}->{value};
}
}
}
foreach (keys %$stats) {
my $name;
$name = $stats->{$_}->{pxname};
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$name !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(long_msg => "skipping Backend '" . $name . "'.", debug => 1);
next;
}
if (defined($self->{option_results}->{add_servers})) {
$self->{backends}->{$_}->{servers} = $stats->{$_}->{servers};
}
$self->{backends}->{$_}->{backend} = $stats->{$_};
$self->{backends}->{$_}->{display} = $name;
}
if (scalar(keys %{$self->{backends}}) <= 0) {
$self->{output}->add_option_msg(short_msg => "No Backend found.");
$self->{output}->option_exit();
}
$self->{cache_name} = 'haproxy_' . $self->{mode} . '_' . $options{custom}->get_hostname() . '_' .
(defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' .
(defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all'));
}
1;
__END__
=head1 MODE
Check HAProxy backend usage.
=over 8
=item B<--add-servers>
Also display and monitor Servers related to a given backend.
=item B<--filter-counters>
Define which counters should appear in the performance data (metrics).
This option will be treated as a regular expression.
Example: C<--filter-counters='^total-connections$'>.
=item B<--filter-name>
Define which backends should be monitored based on their names.
This option will be treated as a regular expression.
=item B<--warning-backend-status>
Define the conditions to match for the backend status to be WARNING.
You can use the following variables: %{status}.
Example: C<--warning-backend-status='%{status} !~ /UP/i'>
=item B<--critical-backend-status>
Define the conditions to match for the backend status to be CRITICAL.
Default: C<'%{status} !~ /UP/i'>.
You can use the following variables: C<%{status}>.
Example: C<--critical-backend-status='%{status} !~ /UP/i'>
=item B<--warning-server-status>
Define the conditions to match for the server status to be WARNING.
You can use the following variables: C<%{status}>.
Example: C<--warning-backend-status='%{status} !~ /UP/i'>
=item B<--critical-server-status>
Define the conditions to match for the status to be CRITICAL. Default: C<'%{status} !~ /UP/i'>.
You can use the following variables: C<%{status}>.
Example: C<--critical-backend-status='%{status} !~ /UP/i'>
=item B<--warning-backend-current-queue>
Thresholds.
=item B<--critical-backend-current-queue>
Thresholds.
=item B<--warning-backend-current-session-rate>
Thresholds.
=item B<--critical-backend-current-session-rate>
Thresholds.
=item B<--warning-backend-max-session-rate>
Thresholds.
=item B<--critical-backend-max-session-rate>
Thresholds.
=item B<--warning-backend-current-sessions>
Thresholds.
=item B<--critical-backend-current-sessions>
Thresholds.
=item B<--warning-backend-total-sessions>
Thresholds.
=item B<--critical-backend-total-sessions>
Thresholds.
=item B<--warning-backend-traffic-in>
Thresholds in b/s.
=item B<--critical-backend-traffic-in>
Thresholds in b/s.
=item B<--warning-backend-traffic-out>
Thresholds in b/s.
=item B<--critical-backend-traffic-out>
Thresholds in b/s.
=item B<--warning-backend-denied-requests>
Thresholds.
=item B<--critical-backend-denied-requests>
Thresholds.
=item B<--warning-backend-denied-responses>
Thresholds.
=item B<--critical-backend-denied-responses>
Thresholds.
=item B<--warning-backend-connections-errors>
Thresholds.
=item B<--critical-backend-connections-errors>
Thresholds.
=item B<--warning-backend-responses-errors>
Thresholds.
=item B<--critical-backend-responses-errors>
Thresholds.
=item B<--warning-server-current-sessions>
Thresholds.
=item B<--critical-server-current-sessions>
Thresholds.
=item B<--warning-server-current-session-rate>
Thresholds.
=item B<--critical-server-current-session-rate>
Thresholds.
=item B<--warning-server-max-session-rate>
Thresholds.
=item B<--critical-server-max-session-rate>
Thresholds.
=item B<--warning-server-denied-responses>
Thresholds.
=item B<--critical-server-denied-responses>
Thresholds.
=item B<--warning-server-connections-errors>
Thresholds.
=item B<--critical-server-connections-errors>
Thresholds.
=item B<--warning-server-responses-errors>
Thresholds.
=item B<--critical-server-responses-errors>
Thresholds.
=back
=cut

View File

@ -0,0 +1,476 @@
#
# Copyright 2025 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::haproxy::web::mode::frontendusage;
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_ng);
sub prefix_frontend_output {
my ($self, %options) = @_;
return "Frontend '" . $options{instance_value}->{display} . "' ";
}
sub prefix_listener_output {
my ($self, %options) = @_;
return "Listener '" . $options{instance_value}->{svname} . "' ";
}
sub prefix_global_frontend_output {
my ($self, %options) = @_;
return 'frontend ';
}
sub frontend_long_output {
my ($self, %options) = @_;
return "Frontend '" . $options{instance_value}->{display} . "':";
}
sub custom_status_output {
my ($self, %options) = @_;
return sprintf("status: %s", $self->{result_values}->{status});
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'frontends', type => 3, cb_prefix_output => 'prefix_frontend_output', cb_long_output => 'frontend_long_output', message_multiple => 'All frontends are ok', indent_long_output => ' ', skipped_code => { -10 => 1 },
group => [
{ name => 'frontend', type => 0, cb_prefix_output => 'prefix_global_frontend_output' },
{ name => 'listeners', type => 1, display_long => 1, cb_prefix_output => 'prefix_listener_output', message_multiple => 'listeners are ok', skipped_code => { -10 => 1 } }
]
}
];
$self->{maps_counters}->{frontend} = [
{
label => 'frontend-status',
type => 2,
critical_default => '%{status} !~ /OPEN/i',
set => {
key_values => [ { name => 'status' }, { name => 'pxname' } ],
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
},
{ label => 'frontend-current-session-rate', nlabel => 'frontend.session.current.rate.countpersecond', set => {
key_values => [ { name => 'rate' }, { name => 'pxname' } ],
output_template => 'current session rate: %s/s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'frontend-max-session-rate', nlabel => 'frontend.session.max.rate.countpersecond', set => {
key_values => [ { name => 'rate_max' }, { name => 'pxname' } ],
output_template => 'max session rate: %s/s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'frontend-current-sessions', nlabel => 'frontend.sessions.current.count', set => {
key_values => [ { name => 'scur' }, { name => 'pxname' } ],
output_template => 'current sessions: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'frontend-total-sessions', nlabel => 'frontend.sessions.total.count', set => {
key_values => [ { name => 'stot' }, { name => 'pxname' } ],
output_template => 'total sessions: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'frontend-max-sessions', nlabel => 'frontend.sessions.maximum.count', set => {
key_values => [ { name => 'smax' }, { name => 'pxname' } ],
output_template => 'max sessions: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'frontend-traffic-in', nlabel => 'frontend.traffic.in.bitpersecond', set => {
key_values => [ { name => 'bin', per_second => 1 }, { name => 'pxname' } ],
output_template => 'traffic in: %s %s/s',
output_change_bytes => 2,
perfdatas => [
{ template => '%.2f', min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'frontend-traffic-out', nlabel => 'frontend.traffic.out.bitpersecond', set => {
key_values => [ { name => 'bout', per_second => 1 }, { name => 'pxname' } ],
output_template => 'traffic out: %s %s/s',
output_change_bytes => 2,
perfdatas => [
{ template => '%.2f', min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'frontend-denied-requests', nlabel => 'frontend.requests.denied.count', set => {
key_values => [ { name => 'dreq' }, { name => 'pxname' } ],
output_template => 'denied requests: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'frontend-denied-responses', nlabel => 'frontend.responses.denied.count', set => {
key_values => [ { name => 'dresp' }, { name => 'pxname' } ],
output_template => 'denied responses: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'pxname' }
]
}
},
{ label => 'frontend-errors-requests', nlabel => 'frontend.requests.error.count', set => {
key_values => [ { name => 'ereq' }, { name => 'pxname' } ],
output_template => 'error requests: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'pxname' }
]
}
}
];
$self->{maps_counters}->{listeners} = [
{
label => 'listener-status',
type => 2,
critical_default => '%{status} !~ /OPEN/i',
set => {
key_values => [ { name => 'status' }, { name => 'pxname' } ],
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
},
{ label => 'listener-current-sessions', nlabel => 'listener.sessions.current.count', set => {
key_values => [ { name => 'scur' }, { name => 'svname' } ],
output_template => 'current sessions: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'svname' }
]
}
},
{ label => 'listener-denied-requests', nlabel => 'listener.requests.denied.count', set => {
key_values => [ { name => 'dreq' }, { name => 'svname' } ],
output_template => 'denied requests: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'svname' }
]
}
},
{ label => 'listener-denied-responses', nlabel => 'listener.responses.denied.count', set => {
key_values => [ { name => 'dresp' }, { name => 'svname' } ],
output_template => 'denied responses: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'svname' }
]
}
},
{ label => 'listener-errors-requests', nlabel => 'listener.requests.error.count', set => {
key_values => [ { name => 'ereq' }, { name => 'svname' } ],
output_template => 'error requests: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1, instance_use => 'svname' }
]
}
},
{ label => 'listener-traffic-in', nlabel => 'listener.traffic.in.bitpersecond', set => {
key_values => [ { name => 'bin', per_second => 1 }, { name => 'pxname' } ],
output_template => 'traffic in: %s %s/s',
output_change_bytes => 2,
perfdatas => [
{ template => '%.2f', min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'svname' }
]
}
},
{ label => 'listener-traffic-out', nlabel => 'listener.traffic.out.bitpersecond', set => {
key_values => [ { name => 'bout', per_second => 1 }, { name => 'svname' } ],
output_template => 'traffic out: %s %s/s',
output_change_bytes => 2,
perfdatas => [
{ template => '%.2f', min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'svname' }
]
}
}
];
}
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 => {
'add-listeners' => { name => 'add_listeners' },
'filter-name:s' => { name => 'filter_name' }
});
return $self;
}
sub manage_selection {
my ($self, %options) = @_;
my $result = $options{custom}->get_stats();
my $stats;
foreach (@$result) {
foreach my $entry (@$_) {
if ($entry->{objType} eq 'Frontend') {
$stats->{$entry->{proxyId}}->{$entry->{field}->{name}} = $entry->{value}->{value};
}
if ($entry->{objType} eq 'Listener') {
$stats->{$entry->{proxyId}}->{listeners}->{$entry->{id}}->{$entry->{field}->{name}} = $entry->{value}->{value};
}
}
}
foreach (keys %$stats) {
my $name;
$name = $stats->{$_}->{pxname};
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$name !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(long_msg => "skipping frontend '" . $name . "'.", debug => 1);
next;
}
if (defined($self->{option_results}->{add_listeners})) {
$self->{frontends}->{$_}->{listeners} = $stats->{$_}->{listeners};
}
$self->{frontends}->{$_}->{frontend} = $stats->{$_};
$self->{frontends}->{$_}->{display} = $name;
}
if (scalar(keys %{$self->{frontends}}) <= 0) {
$self->{output}->add_option_msg(short_msg => "No Frontend found.");
$self->{output}->option_exit();
}
$self->{cache_name} = 'haproxy_' . $self->{mode} . '_' . $options{custom}->get_hostname() . '_' .
(defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' .
(defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all'));
}
1;
__END__
=head1 MODE
Check HAProxy frontend usage.
=over 8
=item B<--add-listeners>
Also display and monitor listeners related to a given frontend.
=item B<--filter-counters>
Define which counters should appear in the performance data (metrics).
This option will be treated as a regular expression.
Example: --filter-counters='^total-connections$'.
=item B<--filter-name>
Define which frontends should be monitored based on their names.
This option will be treated as a regular expression.
=item B<--warning-frontend-status>
Define the conditions to match for the status to be B<WARNING>.
You can use the following variables: C<%{status}>.
Example: C<--warning-frontend-status='%{status} !~ /UP/i'>
=item B<--critical-frontend-status>
Define the conditions to match for the status to be B<CRITICAL>. Default: C<%{status} !~ /OPEN/i>.
You can use the following variables: C<%{status}>.
Example: C<--critical-frontend-status='%{status} !~ /UP/i'>
=item B<--warning-listener-status>
Define the conditions to match for the status to be B<WARNING>
You can use the following variables: C<%{status}>.
Example: C<--warning-listener-status='%{status} !~ /UP/i'>
=item B<--critical-listener-status>
Define the conditions to match for the status to be B<CRITICAL>. Default: C<%{status} !~ /OPEN/i>.
You can use the following variables: C<%{status}>.
Example: C<--critical-listener-status='%{status} !~ /UP/i'>
=item B<--warning-frontend-current-session-rate>
Thresholds.
=item B<--critical-frontend-current-session-rate>
Thresholds.
=item B<--warning-frontend-max-session-rate>
Thresholds.
=item B<--critical-frontend-max-session-rate>
Thresholds.
=item B<--warning-frontend-current-sessions>
Thresholds.
=item B<--critical-frontend-current-sessions>
Thresholds.
=item B<--warning-frontend-total-sessions>
Thresholds.
=item B<--critical-frontend-total-sessions>
Thresholds.
=item B<--warning-frontend-max-sessions>
Thresholds.
=item B<--critical-frontend-max-sessions>
Thresholds.
=item B<--warning-frontend-traffic-in>
Thresholds in b/s.
=item B<--critical-frontend-traffic-in>
Thresholds in b/s.
=item B<--warning-frontend-traffic-out>
Thresholds in b/s.
=item B<--critical-frontend-traffic-out>
Thresholds in b/s.
=item B<--warning-frontend-denied-requests>
Thresholds.
=item B<--critical-frontend-denied-requests>
Thresholds.
=item B<--warning-frontend-denied-responses>
Thresholds.
=item B<--critical-frontend-denied-responses>
Thresholds.
=item B<--warning-frontend-errors-requests>
Thresholds.
=item B<--critical-frontend-errors-requests>
Thresholds.
=item B<--warning-listener-current-sessions>
Thresholds.
=item B<--critical-listener-current-sessions>
Thresholds.
=item B<--warning-listener-denied-requests>
Thresholds.
=item B<--critical-listener-denied-requests>
Thresholds.
=item B<--warning-listener-denied-responses>
Thresholds.
=item B<--critical-listener-denied-responses>
Thresholds.
=item B<--warning-listener-errors-requests>
Thresholds.
=item B<--critical-listener-errors-requests>
Thresholds.
=item B<--warning-listener-traffic-in>
Thresholds in b/s.
=item B<--critical-listener-traffic-in>
Thresholds in b/s.
=item B<--warning-listener-traffic-out>
Thresholds in b/s.
=item B<--critical-listener-traffic-out>
Thresholds in b/s.
=back
=cut

View File

@ -0,0 +1,117 @@
#
# Copyright 2025 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::haproxy::web::mode::listobjects;
use base qw(centreon::plugins::mode);
use strict;
use warnings;
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-object-type:s' => { name => 'filter_objtype', default => 'frontend|backend' }
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
sub manage_selection {
my ($self, %options) = @_;
my $results = $options{custom}->get_stats();
my $backends;
foreach (@$results) {
foreach my $entry (@$_) {
next if (defined($self->{option_results}->{filter_objtype}) && $self->{option_results}->{filter_objtype} ne ''
&& lc($entry->{objType}) !~ /$self->{option_results}->{filter_objtype}/);
$backends->{$entry->{proxyId}}->{type} = lc($entry->{objType});
next if ($entry->{field}->{name} !~ /^(pxname|status)$/);
$backends->{$entry->{proxyId}}->{$entry->{field}->{name}} = $entry->{value}->{value};
}
}
return $backends;
}
sub run {
my ($self, %options) = @_;
my $backends = $self->manage_selection(%options);
foreach (sort keys %$backends) {
$self->{output}->output_add(
long_msg => sprintf("[name = %s][status = %s][type = %s]", $backends->{$_}->{pxname}, $backends->{$_}->{status}, $backends->{$_}->{type})
);
}
$self->{output}->output_add(severity => 'OK', short_msg => 'HAProxy objects:');
$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','status','type']);
}
sub disco_show {
my ($self, %options) = @_;
my $backends = $self->manage_selection(%options);
foreach (sort keys %$backends) {
$self->{output}->add_disco_entry(
name => $backends->{$_}->{pxname},
status => $backends->{$_}->{status},
type => $backends->{$_}->{type},
);
}
}
1;
__END__
=head1 MODE
List HAProxy objects (Backends & Frontends).
=over 8
=item B<--filter-object-type>
Filter object type (can be a regexp).
=item B<--filter-name>
Filter object name (can be a regexp).
=back
=cut

View File

@ -0,0 +1,51 @@
#
# Copyright 2025 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::haproxy::web::plugin;
use strict;
use warnings;
use base qw(centreon::plugins::script_custom);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$self->{version} = '1.0';
$self->{modes} = {
'backend-usage' => 'apps::haproxy::web::mode::backendusage',
'frontend-usage' => 'apps::haproxy::web::mode::frontendusage',
'list-objects' => 'apps::haproxy::web::mode::listobjects'
};
$self->{custom_modes}->{api} = 'apps::haproxy::web::custom::api';
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check HAProxy stats using HTTP stats page.
=cut

View File

@ -61,8 +61,9 @@ sub set_counters {
$self->{maps_counters}->{global} = [
{ label => 'scenario-status',
type => 2,
warning_default => '%{status} !~ "Success"',
warning_default => '%{status} =~ /(Aborted|Stopped|Excluded|Degraded)/',
critical_default => '%{status} =~ "Failure"',
unknown_default => '%{status} =~ /(Unknown|No execution)/',
set => {
key_values => [ { name => 'status' }, { name => 'num_status' }, { name => 'display' } ],
closure_custom_output => $self->can('custom_status_output'),
@ -133,7 +134,7 @@ sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
$self->{timeframe} = defined($self->{option_results}->{timeframe}) && $self->{option_results}->{timeframe} ne '' ? $self->{option_results}->{timeframe} : '900';
$self->{timeframe} = defined($self->{option_results}->{timeframe}) && $self->{option_results}->{timeframe} ne '' ? $self->{option_results}->{timeframe} : '7500';
}
my $status_mapping = {
@ -220,20 +221,24 @@ Check ip-label Ekara scenarios.
=item B<--timeframe>
Set timeframe period in seconds. (default: 900)
Example: --timeframe='3600' will check the last hour
Set timeframe period in seconds. (default: 7500)
Example: C<--timeframe='3600'> will check the last hour.
Note: If the API/Poller is overloaded, it is preferable to refine
this value according to the highest check frequency in the scenario.
=item B<--filter-type>
Filter by scenario type.
Can be: 'WEB', 'HTTPR', 'BROWSER PAGE LOAD'
=item B<--unknown-scenario-status>
Unknown threshold for scenario status (default: C<%{status} !~ /(Unknown|No execution)/>).
Syntax: C<--unknown-scenario-status='%{status} =~ "xxx"'>
=item B<--warning-scenario-status>
Warning threshold for scenario status (default: '%{status} !~ "Success"').
Syntax: --warning-scenario-status='%{status} =~ "xxx"'
Warning threshold for scenario status (default: C<%{status} !~ /(Aborted|Stopped|Excluded|Degraded)/>).
Syntax: C<--warning-scenario-status='%{status} =~ "xxx"'>
=item B<--critical-scenario-status>

View File

@ -0,0 +1,322 @@
#
# Copyright 2025 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::podman::restapi::custom::api;
use strict;
use warnings;
use centreon::plugins::http;
use centreon::plugins::misc;
use JSON::XS;
sub new {
my ($class, %options) = @_;
my $self = {};
bless $self, $class;
if (!defined($options{output})) {
print "Class Custom: Need to specify 'output' argument.\n";
exit 3;
}
if (!defined($options{options})) {
$options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument.");
$options{output}->option_exit();
}
if (!defined($options{noptions})) {
$options{options}->add_options(arguments => {
'hostname:s' => { name => 'hostname' },
'port:s' => { name => 'port' },
'proto:s' => { name => 'proto' },
'url-path:s' => { name => 'url_path' },
'timeout:s' => { name => 'timeout' }
});
# curl --cacert /path/to/ca.crt --cert /path/to/podman.crt --key /path/to/podman.key https://localhost:8080/v5.0.0/libpod/info
# curl --unix-socket $XDG_RUNTIME_DIR/podman/podman.sock 'http://d/v5.0.0/libpod/pods/stats?namesOrIDs=blog' | jq
}
$options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1);
$self->{output} = $options{output};
$self->{http} = centreon::plugins::http->new(%options, default_backend => 'curl');
return $self;
}
sub set_options {
my ($self, %options) = @_;
$self->{option_results} = $options{option_results};
}
sub set_defaults {}
sub check_options {
my ($self, %options) = @_;
$self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : '';
$self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https';
$self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 443;
$self->{url_path} = (defined($self->{option_results}->{url_path})) ? $self->{option_results}->{url_path} : '/v5.0.0/libpod/';
$self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 30;
if ($self->{hostname} eq '') {
$self->{output}->add_option_msg(short_msg => 'Need to specify hostname option.');
$self->{output}->option_exit();
}
$self->{http}->set_options(%{$self->{option_results}});
return 0;
}
sub json_decode {
my ($self, %options) = @_;
$options{content} =~ s/\r//mg;
my $decoded;
eval {
$decoded = JSON::XS->new->utf8->decode($options{content});
};
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@");
$self->{output}->option_exit();
}
return $decoded;
}
sub build_options_for_httplib {
my ($self, %options) = @_;
$self->{option_results}->{hostname} = $self->{hostname};
$self->{option_results}->{port} = $self->{port};
$self->{option_results}->{proto} = $self->{proto};
$self->{option_results}->{timeout} = $self->{timeout};
}
sub settings {
my ($self, %options) = @_;
$self->build_options_for_httplib();
$self->{http}->add_header(key => 'Accept', value => 'application/json');
$self->{http}->set_options(%{$self->{option_results}});
}
sub request {
my ($self, %options) = @_;
my $endpoint = $options{full_endpoint};
if (!defined($endpoint)) {
$endpoint = $self->{url_path} . $options{endpoint};
}
$self->settings();
my $content = $self->{http}->request(
method => $options{method},
url_path => $endpoint,
get_param => $options{get_param},
header => [
'Accept: application/json'
],
warning_status => '',
unknown_status => '',
critical_status => ''
);
my $decoded = $self->json_decode(content => $content);
if (!defined($decoded)) {
$self->{output}->add_option_msg(short_msg => 'Error while retrieving data (add --debug option for detailed message)');
$self->{output}->option_exit();
}
return $decoded;
}
sub system_info {
my ($self, %options) = @_;
my $results = $self->request(
endpoint => 'info',
method => 'GET'
);
return $results;
}
sub list_containers {
my ($self, %options) = @_;
my $results = $self->request(
endpoint => 'containers/json',
method => 'GET'
);
my $containers = {};
foreach my $container (@{$results}) {
$containers->{$container->{Id}} = {
Name => $container->{Names}->[0],
PodName => $container->{PodName},
State => $container->{State}
};
}
return $containers;
}
sub list_pods {
my ($self, %options) = @_;
my $results = $self->request(
endpoint => 'pods/json',
method => 'GET'
);
my $pods = {};
foreach my $pod (@{$results}) {
$pods->{$pod->{Id}} = {
Name => $pod->{Name},
Status => $pod->{Status}
};
}
return $pods;
}
sub get_pod_infos {
my ($self, %options) = @_;
my $inspect = $self->request(
endpoint => 'pods/' . $options{pod_name} . '/json',
method => 'GET'
);
my $stats = $self->request(
endpoint => 'pods/stats?namesOrIDs=' . $options{pod_name},
method => 'GET'
);
my $pod = {
cpu => 0,
memory => 0,
running_containers => 0,
stopped_containers => 0,
paused_containers => 0,
state => @{$inspect}[0]->{State}
};
foreach my $container (@{$inspect->[0]->{Containers}}) {
$pod->{running_containers}++ if ($container->{State} eq 'running');
$pod->{stopped_containers}++ if ($container->{State} eq 'exited');
$pod->{paused_containers}++ if ($container->{State} eq 'paused');
}
foreach my $container (@{$stats}) {
my $cpu = $container->{CPU};
if ($cpu =~ /^(\d+\.\d+)%/) {
$pod->{cpu} += $1;
}
my $memory = $container->{MemUsage};
if ($memory =~ /^(\d+\.?\d*)([a-zA-Z]+)/) {
$memory = centreon::plugins::misc::convert_bytes(value => $1, unit => $2);
}
$pod->{memory} += $memory;
}
return $pod;
}
sub get_container_infos {
my ($self, %options) = @_;
my $stats = $self->request(
endpoint => 'containers/stats?stream=false&amp;containers=' . $options{container_name},
method => 'GET'
);
my $containers = $self->list_containers();
my $state;
foreach my $container_id (sort keys %{$containers}) {
if ($containers->{$container_id}->{Name} eq $options{container_name}) {
$state = $containers->{$container_id}->{State};
}
}
my $container = {
cpu_usage => $stats->{Stats}->[0]->{CPU},
memory_usage => $stats->{Stats}->[0]->{MemUsage},
io_read => $stats->{Stats}->[0]->{BlockInput},
io_write => $stats->{Stats}->[0]->{BlockOutput},
network_in => $stats->{Stats}->[0]->{NetInput},
network_out => $stats->{Stats}->[0]->{NetOutput},
state => $state
};
return $container;
}
1;
__END__
=head1 NAME
Podman REST API.
=head1 SYNOPSIS
Podman Rest API custom mode.
To connect to the API with a socket, you must add the following command:
C<--curl-opt="CURLOPT_UNIX_SOCKET_PATH => 'PATH_TO_THE_SOCKET'">
If you use a certificate, you must add the following commands:
C<--curl-opt="CURLOPT_CAINFO = 'PATH_TO_THE_CA_CERTIFICATE'">
C<--curl-opt="CURLOPT_SSLCERT => 'PATH_TO_THE_CERTIFICATE'">
C<--curl-opt="CURLOPT_SSLKEY => 'PATH_TO_THE_KEY'">
=head1 REST API OPTIONS
=over 8
=item B<--hostname>
Podman Rest API hostname.
=item B<--port>
Port used (Default: 443)
=item B<--proto>
Specify https if needed (Default: 'https')
=item B<--url-path>
Set path to get Podman Rest API information (Default: '/v5.0.0/libpod/')
=item B<--timeout>
Set timeout in seconds (Default: 30)
=back
=head1 DESCRIPTION
B<custom>.
=cut

View File

@ -0,0 +1,247 @@
#
# Copyright 2025 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::podman::restapi::mode::containerusage;
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) = @_;
$self->{maps_counters_type} = [
{ name => 'container', type => 0 }
];
$self->{maps_counters}->{container} = [
{ label => 'cpu-usage',
nlabel => 'podman.container.cpu.usage.percent',
set => {
key_values => [ { name => 'cpu_usage' } ],
output_template => 'CPU: %.2f%%',
perfdatas => [
{ label => 'cpu',
value => 'cpu_usage',
template => '%.2f',
unit => '%',
min => 0,
max => 100 }
]
}
},
{ label => 'memory-usage',
nlabel => 'podman.container.memory.usage.bytes',
set => {
key_values => [ { name => 'memory_usage' } ],
output_template => 'Memory: %s%s',
output_change_bytes => 1,
perfdatas => [
{ label => 'memory',
value => 'memory_usage',
template => '%s',
unit => 'B',
min => 0 }
]
}
},
{ label => 'read-io',
nlabel => 'podman.container.io.read',
set => {
key_values => [ { name => 'io_read' } ],
output_template => 'Read : %s%s',
output_change_bytes => 1,
perfdatas => [
{ label => 'read.io',
value => 'io_read',
template => '%s',
unit => 'B',
min => 0 }
]
}
},
{ label => 'write-io',
nlabel => 'podman.container.io.write',
set => {
key_values => [ { name => 'io_write' } ],
output_template => 'Write : %s%s',
output_change_bytes => 1,
perfdatas => [
{ label => 'write.io',
value => 'io_write',
template => '%s',
unit => 'B',
min => 0 }
]
}
},
{ label => 'network-in',
nlabel => 'podman.container.network.in',
set => {
key_values => [ { name => 'network_in' } ],
output_template => 'Network in: %s%s',
output_change_bytes => 1,
perfdatas => [
{ label => 'network_in',
value => 'network_in',
template => '%s',
unit => 'B',
min => 0 }
]
}
},
{ label => 'network-out',
nlabel => 'podman.container.network.out',
set => {
key_values => [ { name => 'network_out' } ],
output_template => 'Network out: %s%s',
output_change_bytes => 1,
perfdatas => [
{ label => 'network_out',
value => 'network_out',
template => '%s',
unit => 'B',
min => 0 }
]
}
},
{ label => 'state',
type => 2,
warning_default => '%{state} =~ /Paused/',
critical_default => '%{state} =~ /Exited/',
set => {
key_values => [ { name => 'state' } ],
output_template => 'State: %s',
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 => {
'container-name:s' => { name => 'container_name' }
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
if (centreon::plugins::misc::is_empty($self->{option_results}->{container_name})) {
$self->{output}->add_option_msg(short_msg => "Need to specify --container-name option.");
$self->{output}->option_exit();
}
}
sub manage_selection {
my ($self, %options) = @_;
my $container = $options{custom}->get_container_infos(
container_name => $self->{option_results}->{container_name}
);
$self->{container} = $container;
}
1;
__END__
=head1 MODE
Check container usage.
=over 8
=item B<--container-name>
Container name.
=item B<--warning-cpu-usage>
Threshold warning for CPU usage.
=item B<--critical-cpu-usage>
Threshold critical for CPU usage.
=item B<--warning-memory-usage>
Threshold warning for memory usage.
=item B<--critical-memory-usage>
Threshold critical for memory usage.
=item B<--warning-read-io>
Threshold warning for read IO.
=item B<--critical-read-io>
Threshold critical for read IO.
=item B<--warning-write-io>
Threshold warning for write IO.
=item B<--critical-write-io>
Threshold critical for write IO.
=item B<--warning-network-in>
Threshold warning for network in.
=item B<--critical-network-in>
Threshold critical for network in.
=item B<--warning-network-out>
Threshold warning for network out.
=item B<--critical-network-out>
Threshold critical for network out.
=item B<--warning-container-state>
Define the conditions to match for the state to be WARNING (default: C<'%{state} =~ /Paused/'>).
You can use the following variables: C<%{state}>
=item B<--critical-container-state>
Define the conditions to match for the state to be CRITICAL (default: C<'%{state} =~ /Exited/'>).
You can use the following variables: C<%{state}>
=back
=cut

View File

@ -0,0 +1,94 @@
#
# Copyright 2025 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::podman::restapi::mode::listcontainers;
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 =>
{
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
sub run {
my ($self, %options) = @_;
my $containers = $options{custom}->list_containers();
foreach my $container_id (sort keys %{$containers}) {
$self->{output}->output_add(long_msg => '[id = ' . $container_id . "]" .
" [name = '" . $containers->{$container_id}->{Name} . "']" .
" [pod = '" . $containers->{$container_id}->{PodName} . "']" .
" [state = '" . $containers->{$container_id}->{State} . "']"
);
}
$self->{output}->output_add(severity => 'OK',
short_msg => 'Containers:');
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
$self->{output}->exit();
}
sub disco_format {
my ($self, %options) = @_;
$self->{output}->add_disco_format(elements => [ 'id', 'name', 'pod', 'state' ]);
}
sub disco_show {
my ($self, %options) = @_;
my $containers = $options{custom}->list_containers();
foreach my $container_id (sort keys %{$containers}) {
$self->{output}->add_disco_entry(name => $containers->{$container_id}->{Name},
pod => $containers->{$container_id}->{PodName},
state => $containers->{$container_id}->{State},
id => $container_id,
);
}
}
1;
__END__
=head1 MODE
List containers.
=over 8
=back
=cut

View File

@ -0,0 +1,92 @@
#
# Copyright 2025 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::podman::restapi::mode::listpods;
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 =>
{
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
sub run {
my ($self, %options) = @_;
my $pods = $options{custom}->list_pods();
foreach my $pod_id (sort keys %{$pods}) {
$self->{output}->output_add(long_msg => '[id = ' . $pod_id . "]" .
" [name = '" . $pods->{$pod_id}->{Name} . "']" .
" [status = '" . $pods->{$pod_id}->{Status} . "']"
);
}
$self->{output}->output_add(severity => 'OK',
short_msg => 'Pods:');
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
$self->{output}->exit();
}
sub disco_format {
my ($self, %options) = @_;
$self->{output}->add_disco_format(elements => [ 'id', 'name', 'status' ]);
}
sub disco_show {
my ($self, %options) = @_;
my $pods = $options{custom}->list_pods();
foreach my $pod_id (sort keys %{$pods}) {
$self->{output}->add_disco_entry(name => $pods->{$pod_id}->{Name},
state => $pods->{$pod_id}->{Status},
id => $pod_id,
);
}
}
1;
__END__
=head1 MODE
List pods.
=over 8
=back
=cut

View File

@ -0,0 +1,224 @@
#
# Copyright 2025 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::podman::restapi::mode::podstatus;
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) = @_;
$self->{maps_counters_type} = [
{ name => 'pod', type => 0 }
];
$self->{maps_counters}->{pod} = [
{ label => 'cpu-usage',
nlabel => 'podman.pod.cpu.usage.percent',
set => {
key_values => [ { name => 'cpu' } ],
output_template => 'CPU: %.2f%%',
perfdatas => [
{ label => 'cpu',
value => 'cpu',
template => '%.2f',
unit => '%',
min => 0,
max => 100 }
]
}
},
{ label => 'memory-usage',
nlabel => 'podman.pod.memory.usage.bytes', set => {
key_values => [ { name => 'memory' } ],
output_template => 'Memory: %s%s',
output_change_bytes => 1,
perfdatas => [
{ label => 'memory',
value => 'memory',
template => '%s',
unit => 'B',
min => 0 }
]
}
},
{ label => 'running-containers',
nlabel => 'podman.pod.containers.running.count',
set => {
key_values => [ { name => 'containers_running' } ],
output_template => 'Running containers: %s',
perfdatas => [
{ label => 'containers_running',
value => 'containers_running',
template => '%s',
min => 0 }
]
}
},
{ label => 'stopped-containers',
nlabel => 'podman.pod.containers.stopped.count',
set => {
key_values => [ { name => 'containers_stopped' } ],
output_template => 'Stopped containers: %s',
perfdatas => [
{ label => 'containers_stopped',
value => 'containers_stopped',
template => '%s',
min => 0 }
]
}
},
{ label => 'paused-containers',
nlabel => 'podman.pod.containers.paused.count',
set => {
key_values => [ { name => 'containers_paused' } ],
output_template => 'Paused containers: %s',
perfdatas => [
{ label => 'containers_paused',
value => 'containers_paused',
template => '%s',
min => 0 }
]
}
},
{ label => 'state',
type => 2,
warning_default => '%{state} =~ /Exited/',
critical_default => '%{state} =~ /Degraded/',
set => {
key_values => [ { name => 'state' } ],
output_template => 'State: %s',
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 => {
'pod-name:s' => { name => 'pod_name' }
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
if (centreon::plugins::misc::is_empty($self->{option_results}->{pod_name})) {
$self->{output}->add_option_msg(short_msg => "Need to specify --pod-name option.");
$self->{output}->option_exit();
}
}
sub manage_selection {
my ($self, %options) = @_;
my $result = $options{custom}->get_pod_infos(
pod_name => $self->{option_results}->{pod_name}
);
$self->{pod} = {
cpu => $result->{cpu},
memory => $result->{memory},
containers_running => $result->{running_containers},
containers_stopped => $result->{stopped_containers},
containers_paused => $result->{paused_containers},
state => $result->{state}
};
}
1;
__END__
=head1 MODE
Check node status.
=over 8
=item B<--pod-name>
Pod name.
=item B<--warning-cpu-usage>
Threshold warning for CPU usage.
=item B<--critical-cpu-usage>
Threshold critical for CPU usage.
=item B<--warning-memory-usage>
Threshold warning for memory usage.
=item B<--critical-memory-usage>
Threshold critical for memory usage.
=item B<--warning-running-containers>
Threshold warning for running containers.
=item B<--critical-running-containers>
Threshold critical for running containers.
=item B<--warning-stopped-containers>
Threshold warning for stopped containers.
=item B<--critical-stopped-containers>
Threshold critical for stopped containers.
=item B<--warning-paused-containers>
Threshold warning for paused containers.
=item B<--critical-paused-containers>
Threshold critical for paused containers.
=item B<--warning-state>
Define the conditions to match for the state to be WARNING (default: C<'%{state} =~ /Exited/'>).
You can use the following variables: C<%{state}>
=item B<--critical-state>
Define the conditions to match for the state to be CRITICAL (default: C<'%{state} =~ /Degraded/'>).
You can use the following variables: C<%{state}>
=back
=cut

View File

@ -0,0 +1,240 @@
#
# Copyright 2025 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::podman::restapi::mode::systemstatus;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold);
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'system', type => 0 }
];
$self->{maps_counters}->{system} = [
{ label => 'cpu-usage',
nlabel => 'podman.system.cpu.usage.percent',
set => {
key_values => [
{ name => 'cpu_usage' }
],
output_template => 'CPU: %.2f%%',
perfdatas => [
{ label => 'cpu',
template => '%.2f',
min => 0,
max => 100,
unit => '%' }
]
}
},
{ label => 'memory-usage',
nlabel => 'podman.system.memory.usage.bytes',
set => {
key_values => [
{ name => 'memory_usage' }
],
output_template => 'Memory: %s%s',
output_change_bytes => 1,
perfdatas => [
{ label => 'memory',
template => '%s',
min => 0,
unit => 'B' }
]
}
},
{ label => 'swap-usage',
nlabel => 'podman.system.swap.usage.bytes',
set => {
key_values => [
{ name => 'swap_usage' }
],
output_template => 'Swap: %s%s',
output_change_bytes => 1,
perfdatas => [
{ label => 'swap',
template => '%s',
min => 0,
unit => 'B' }
]
}
},
{ label => 'containers-running',
nlabel => 'podman.system.containers.running.count',
set => {
key_values => [
{ name => 'running_containers' },
{ name => 'total_containers' }
],
output_template => 'Running containers: %s',
perfdatas => [
{ label => 'running_containers',
template => '%s',
min => 0,
max => 'total_containers',
unit => '' }
]
}
},
{ label => 'containers-stopped',
nlabel => 'podman.system.containers.stopped.count',
set => {
key_values => [
{ name => 'stopped_containers' },
{ name => 'total_containers' }
],
output_template => 'Stopped containers: %s',
perfdatas => [
{ label => 'stopped_containers',
template => '%s',
min => 0,
max => 'total_containers',
unit => '' }
]
}
},
{ label => 'uptime',
nlabel => 'podman.system.uptime.seconds',
set => {
key_values => [
{ name => 'uptime' }
],
output_template => 'Uptime: %s s',
perfdatas => [
{ label => 'uptime',
template => '%s',
min => 0,
unit => 's' }
]
}
}
];
}
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 => {});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
}
sub manage_selection {
my ($self, %options) = @_;
my $results = $options{custom}->system_info();
my $uptime_string = $results->{host}->{uptime};
my $uptime = 0;
if ($uptime_string =~ /(\d+)h/) {
$uptime += $1 * 3600;
}
if ($uptime_string =~ /(\d+)m/) {
$uptime += $1 * 60;
}
if ($uptime_string =~ /(\d+)s/) {
$uptime += $1;
}
$self->{system} = {
cpu_usage => $results->{host}->{cpuUtilization}->{userPercent} + $results->{host}->{cpuUtilization}->{systemPercent},
memory_usage => $results->{host}->{memTotal} - $results->{host}->{memFree},
swap_usage => $results->{host}->{swapTotal} - $results->{host}->{swapFree},
running_containers => $results->{store}->{containerStore}->{running},
stopped_containers => $results->{store}->{containerStore}->{stopped},
total_containers => $results->{store}->{containerStore}->{number},
uptime => $uptime
};
}
1;
__END__
=head1 MODE
Check Podman system status.
=over 8
=item B<--warning-cpu-usage>
Threshold warning in percent for CPU usage.
=item B<--critical-cpu-usage>
Threshold critical in percent for CPU usage.
=item B<--warning-memory-usage>
Threshold warning in bytes for memory usage.
=item B<--critical-memory-usage>
Threshold critical in bytes for memory usage.
=item B<--warning-swap-usage>
Threshold warning in bytes for swap usage.
=item B<--critical-swap-usage>
Threshold critical in bytes for swap usage.
=item B<--warning-containers-running>
Threshold warning for the number of running containers.
=item B<--critical-containers-running>
Threshold critical for the number of running containers.
=item B<--warning-containers-stopped>
Threshold warning for the number of stopped containers.
=item B<--critical-containers-stopped>
Threshold critical for the number of stopped containers.
=item B<--warning-uptime>
Threshold warning for uptime in seconds.
=item B<--critical-uptime>
Threshold critical for uptime in seconds.
=back
=cut

View File

@ -0,0 +1,53 @@
#
# Copyright 2024 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::podman::restapi::plugin;
use strict;
use warnings;
use base qw(centreon::plugins::script_custom);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$self->{version} = '1.0';
$self->{modes} = {
'container-usage' => 'apps::podman::restapi::mode::containerusage',
'list-containers' => 'apps::podman::restapi::mode::listcontainers',
'list-pods' => 'apps::podman::restapi::mode::listpods',
'pod-status' => 'apps::podman::restapi::mode::podstatus',
'system-status' => 'apps::podman::restapi::mode::systemstatus'
};
$self->{custom_modes}->{api} = 'apps::podman::restapi::custom::api';
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check Podman and containers through its HTTPS Rest API (https://docs.podman.io/en/latest/_static/api.html).
=cut

View File

@ -459,7 +459,7 @@ Critical threshold (default: on total matching elements)
=item B<--threshold-value>
Define the scope to which the numeric thresholds apply.
Possible values for this option: 'value' to check numeric values, 'count' to check the number of values (default: count).
Possible values for this option: 'values' to check numeric values, 'count' to check the number of values (default: count).
=item B<--warning-string>

View File

@ -314,9 +314,9 @@ sub manage_selection {
name => $self->{sdwan}->{$_}->{name},
vdom => $result->{vdom},
ifName => $result->{ifName},
in => $result->{traffic_in} * 1000 * 1000,
out => $result->{traffic_out} * 1000 * 1000,
bi => $result->{traffic_bi} * 1000 * 1000,
in => $result->{traffic_in} * 1000,
out => $result->{traffic_out} * 1000,
bi => $result->{traffic_bi} * 1000,
};
$self->{sdwan}->{$_}->{jitter} = {

View File

@ -116,7 +116,7 @@ Can use special variables like: %{status}, %{display}
=item B<--critical-*>
Define the conditions to match for the status to be CRITICAL. (default: %{status} =~ /red/).
Can be: 'dns-connectivity', 'localdns-connectivity', 'cloud-connectivity', 'ad-connectivity'.
Can be: 'dns-status', 'localdns-status', 'cloud-status', 'ad-status'.
Can use special variables like: %{status}, %{display}

View File

@ -0,0 +1,191 @@
#
# 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::cyberoam::snmp::mode::hastatus;
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 = "HA is '" . $self->{result_values}->{hastatus} . "' - ";
$msg .= "Current HA State: '" . $self->{result_values}->{hastate} . "' - ";
$msg .= "Peer HA State: '" . $self->{result_values}->{peer_hastate} . "' - ";
$msg .= "HA Port: '" . $self->{result_values}->{ha_port} . "' - ";
$msg .= "HA IP: '" . $self->{result_values}->{ha_ip} . "' - ";
$msg .= "Peer IP: '" . $self->{result_values}->{ha_peer_ip} . "'";
return $msg;
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'ha', type => 0 },
];
$self->{maps_counters}->{ha} = [
{
label => 'status',
type => 2,
set => {
key_values => [
{ name => 'hastate' },
{ name => 'hastatus' },
{ name => 'peer_hastate' },
{ name => 'ha_port' },
{ name => 'ha_ip' },
{ name => 'ha_peer_ip' }
],
default_critical => '%{hastatus} =~ /^enabled$/ && %{hastate} =~ /^faulty$/',
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 => {
'no-ha-status:s' => { name => 'no_ha_status', default => 'UNKNOWN' }
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
$self->change_macros(macros => [ 'warning_status', 'critical_status' ]);
}
# snmptranslate -Td .1.3.6.1.4.1.2604.5.1.4.1.0
# SFOS-FIREWALL-MIB::sfosHAStatus.0
# sfosHAStatus OBJECT-TYPE
# -- FROM SFOS-FIREWALL-MIB
# -- TEXTUAL CONVENTION HaStatusType
# SYNTAX INTEGER {disabled(0), enabled(1)}
# MAX-ACCESS read-only
# STATUS current
# DESCRIPTION " "
# ::= { iso(1) org(3) dod(6) internet(1) private(4) enterprises(1) sophosMIB(2604) sfosXGMIB(5) sfosXGMIBObjects(1) sfosXGHAStats(4) sfosHAStatus(1) 0 }
my %map_status = (
0 => 'disabled',
1 => 'enabled'
);
# snmptranslate -Td .1.3.6.1.4.1.2604.5.1.4.4.0
# SFOS-FIREWALL-MIB::sfosDeviceCurrentHAState.0
# sfosDeviceCurrentHAState OBJECT-TYPE
# -- FROM SFOS-FIREWALL-MIB
# -- TEXTUAL CONVENTION HaState
# SYNTAX INTEGER {notapplicable(0), auxiliary(1), standAlone(2), primary(3), faulty(4), ready(5)}
# MAX-ACCESS read-only
# STATUS current
# DESCRIPTION "HA State of current Device"
# ::= { iso(1) org(3) dod(6) internet(1) private(4) enterprises(1) sophosMIB(2604) sfosXGMIB(5) sfosXGMIBObjects(1) sfosXGHAStats(4) sfosDeviceCurrentHAState(4) 0 }
my %map_state = (
0 => 'notapplicable',
1 => 'auxiliary',
2 => 'standAlone',
3 => 'primary',
4 => 'faulty',
5 => 'ready'
);
sub manage_selection {
my ($self, %options) = @_;
my $oid_ha_status = '.1.3.6.1.4.1.2604.5.1.4.1.0';
my $oid_ha_state = '.1.3.6.1.4.1.2604.5.1.4.4.0';
my $oid_peer_ha_state = '.1.3.6.1.4.1.2604.5.1.4.5.0';
my $oid_ha_port = '.1.3.6.1.4.1.2604.5.1.4.8.0';
my $oid_ha_ip = '.1.3.6.1.4.1.2604.5.1.4.9.0';
my $oid_ha_peer_ip = '.1.3.6.1.4.1.2604.5.1.4.10.0';
$self->{ha} = {};
my $result = $options{snmp}->get_leef(
oids =>
[ $oid_ha_status, $oid_ha_state, $oid_peer_ha_state, $oid_ha_port, $oid_ha_ip, $oid_ha_peer_ip ],
nothing_quit =>
1
);
if ($result->{$oid_ha_status} == 0 or $result->{$oid_ha_state} == 0) {
$self->{output}->output_add(
severity => $self->{option_results}->{no_ha_status},
short_msg => sprintf("Looks like HA is not enabled, or not applicable .."),
long_msg => sprintf(
"HA Enabled : '%u' HA Status : '%s'",
$map_status{$result->{$oid_ha_status}}, $map_status{$result->{$oid_ha_state}}
),
);
$self->{output}->display();
$self->{output}->exit();
}
$self->{ha} = {
hastatus => $map_status{$result->{$oid_ha_status}},
hastate => $map_state{$result->{$oid_ha_state}},
peer_hastate => $map_state{$result->{$oid_peer_ha_state}},
ha_port => $result->{$oid_ha_port},
ha_ip => $result->{$oid_ha_ip},
ha_peer_ip => $result->{$oid_ha_peer_ip}
};
}
1;
__END__
=head1 MODE
Check current HA-State.
HA-States: notapplicable, auxiliary, standAlone, primary, faulty, ready
=over 8
=item B<--warning-status>
Trigger warning on %{hastatus} or %{hastate} or %{peer_hastate} values.
=item B<--critical-status>
Trigger critical on %{hastatus} or %{hastate} or %{peer_hastate} values.
(default: '%{hastatus} =~ /^enabled$/ && %{hastate} =~ /^faulty$/').
=item B<--no-ha-status>
Status to return when HA not running or not installed (default: 'UNKNOWN').
=back
=cut

View File

@ -0,0 +1,294 @@
#
# 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::cyberoam::snmp::mode::license;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
use centreon::plugins::misc;
use POSIX;
use Time::Local;
use DateTime::Format::Strptime;
my $unitdiv = { s => 1, w => 604800, d => 86400, h => 3600, m => 60 };
my $unitdiv_long = { s => 'seconds', w => 'weeks', d => 'days', h => 'hours', m => 'minutes' };
sub custom_expires_perfdata {
my ($self, %options) = @_;
$self->{output}->perfdata_add(
nlabel => $self->{nlabel} . '.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{unit} },
unit => $self->{instance_mode}->{option_results}->{unit},
instances => $self->{result_values}->{name},
value => floor($self->{result_values}->{expires_seconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }),
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
min => 0
);
}
sub custom_expires_threshold {
my ($self, %options) = @_;
return $self->{perfdata}->threshold_check(
value =>
floor($self->{result_values}->{expires_seconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }),
threshold =>
[
{ label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' },
{ label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' },
{ label => 'unknown-' . $self->{thlabel}, exit_litteral => 'unknown' }
]
);
}
sub custom_status_output {
my ($self, %options) = @_;
return 'status: ' . $self->{result_values}->{status} . ', expires in ' . $self->{result_values}->{expires_human};
}
sub prefix_license_output {
my ($self, %options) = @_;
return sprintf(
"License '%s' ",
$options{instance_value}->{name}
);
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{
name => 'licenses',
type => 1,
cb_prefix_output => 'prefix_license_output',
message_multiple => 'All licenses are ok',
skipped_code => { -10 => 1 }
}
];
$self->{maps_counters}->{licenses} = [
{
label => 'status',
type => 2,
critical_default => '%{status} =~ /expired/i',
set => {
key_values => [ { name => 'name' }, { name => 'status' }, { name => 'expires_human' } ],
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub {return 0;},
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
},
{
label => 'expires',
type => 1,
nlabel => 'license.expires',
set => {
key_values => [ { name => 'expires_seconds' }, { name => 'expires_human' }, { name => 'name' } ],
output_template => 'expires in %s',
output_use => 'expires_human',
closure_custom_perfdata => $self->can('custom_expires_perfdata'),
closure_custom_threshold_check => $self->can('custom_expires_threshold')
}
}
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
'filter-name:s' => { name => 'filter_name' },
'unit:s' => { name => 'unit', default => 's' }
});
return $self;
}
my %map_lic_status = (
0 => 'none',
1 => 'evaluating',
2 => 'notsubscribed',
3 => 'subscribed',
4 => 'expired',
5 => 'deactivated'
);
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
if ($self->{option_results}->{unit} eq '' || !defined($unitdiv->{$self->{option_results}->{unit}})) {
$self->{option_results}->{unit} = 's';
}
}
sub add_license {
my ($self, %options) = @_;
return if (!defined($options{status}));
return if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$options{name} !~ /$self->{option_results}->{filter_name}/);
$self->{licenses}->{ $options{name} } = {
name => $options{name},
status => $options{status},
expires => $options{expires}
};
if (defined($options{expires}) && $options{expires} ne "fail" && $options{status} =~ /subscribed|expired|evaluating/i) {
my $strp = DateTime::Format::Strptime->new(
pattern => '%b %d %Y',
locale => 'en_US',
);
my $dt = $strp->parse_datetime($options{expires});
$self->{licenses}->{ $options{name} }->{expires_seconds} = $dt->epoch - time();
$self->{licenses}->{ $options{name} }->{expires_seconds} = 0 if ($self->{licenses}->{ $options{name} }->{expires_seconds} < 0);
$self->{licenses}->{ $options{name} }->{expires_human} = centreon::plugins::misc::change_seconds(
value => $self->{licenses}->{ $options{name} }->{expires_seconds}
);
} else {
$self->{licenses}->{ $options{name} }->{expires_human} = "n.d.";
}
}
sub manage_selection {
my ($self, %options) = @_;
my $oid_base_fw_lic_status = '.1.3.6.1.4.1.2604.5.1.5.1.1.0';# sfosBaseFWLicRegStatus
my $oid_base_fw_lic_expiry_date = '.1.3.6.1.4.1.2604.5.1.5.1.2.0';# sfosBaseFWLicExpiryDate
my $oid_net_protection_lic_status = '.1.3.6.1.4.1.2604.5.1.5.2.1.0';# sfosNetProtectionLicRegStatus
my $oid_net_protection_lic_expiry_date = '.1.3.6.1.4.1.2604.5.1.5.2.2.0';# sfosNetProtectionLicExpiryDate
my $oid_web_protection_lic_status = '.1.3.6.1.4.1.2604.5.1.5.3.1.0';# sfosWebProtectionLicRegStatus
my $oid_web_protection_lic_expiry_date = '.1.3.6.1.4.1.2604.5.1.5.3.2.0';# sfosWebProtectionLicExpiryDate
my $oid_mail_protection_lic_status = '.1.3.6.1.4.1.2604.5.1.5.4.1.0';# sfosMailProtectionLicRegStatus
my $oid_mail_protection_lic_expiry_date = '.1.3.6.1.4.1.2604.5.1.5.4.2.0';# sfosMailProtectionLicExpiryDate
my $oid_web_server_protection_lic_status = '.1.3.6.1.4.1.2604.5.1.5.5.1';# sfosWebServerProtectionLicRegStatus
my $oid_web_server_protection_lic_expiry_date = '.1.3.6.1.4.1.2604.5.1.5.5.2';# sfosWebServerProtectionLicExpiryDate
my $oid_sand_storm_lic_status = '.1.3.6.1.4.1.2604.5.1.5.6.1';# sfosSandstromLicRegStatus
my $oid_sand_storm_protection_lic_expiry_date = '.1.3.6.1.4.1.2604.5.1.5.6.2';# sfosSandstromLicExpiryDate
my $oid_enhanced_support_lic_status = '.1.3.6.1.4.1.2604.5.1.5.7.1';# sfosEnhancedSupportLicRegStatus
my $oid_enhanced_support_lic_expiry_date = '.1.3.6.1.4.1.2604.5.1.5.7.2';# sfosEnhancedSupportLicExpiryDate
my $oid_enhanced_plus_lic_status = '.1.3.6.1.4.1.2604.5.1.5.8.1';# sfosEnhancedPlusLicRegStatus
my $oid_enhanced_plus_lic_expiry_date = '.1.3.6.1.4.1.2604.5.1.5.8.2';# sfosEnhancedPlusLicExpiryDate
my $oid_central_orchestra_lic_status = '.1.3.6.1.4.1.2604.5.1.5.9.1';# sfosCentralOrchestrationLicRegStatus
my $oid_central_orchestra_lic_expiry_date = '.1.3.6.1.4.1.2604.5.1.5.9.2';# sfosCentralOrchestrationLicExpiryDate
my $result = $options{snmp}->get_leef(
oids => [
$oid_base_fw_lic_status,
$oid_base_fw_lic_expiry_date,
$oid_net_protection_lic_status,
$oid_net_protection_lic_expiry_date,
$oid_web_protection_lic_status,
$oid_web_protection_lic_expiry_date,
$oid_mail_protection_lic_status,
$oid_mail_protection_lic_expiry_date,
# $oid_web_server_protection_lic_status,
# $oid_web_server_protection_lic_expiry_date,
# $oid_sand_storm_lic_status,
# $oid_sand_storm_protection_lic_expiry_date,
# $oid_enhanced_support_lic_status,
# $oid_enhanced_support_lic_expiry_date,
# $oid_enhanced_plus_lic_status,
# $oid_mail_protection_lic_status,
# $oid_enhanced_plus_lic_expiry_date,
# $oid_central_orchestra_lic_status,
# $oid_central_orchestra_lic_expiry_date
],
nothing_quit => 1
);
$self->{licenses} = {};
$self->add_license(
name => 'base_fw',
status => $map_lic_status{$result->{$oid_base_fw_lic_status}},
expires => $result->{$oid_base_fw_lic_expiry_date}
);
$self->add_license(
name => 'net_protection',
status => $map_lic_status{$result->{$oid_net_protection_lic_status}},
expires => $result->{$oid_net_protection_lic_expiry_date}
);
$self->add_license(
name => 'web_protection',
status => $map_lic_status{$result->{$oid_web_protection_lic_status}},
expires => $result->{$oid_web_protection_lic_expiry_date}
);
$self->add_license(
name => 'mail_protection',
status => $map_lic_status{$result->{$oid_mail_protection_lic_status}},
expires => $result->{$oid_mail_protection_lic_expiry_date}
);
}
1;
__END__
=head1 MODE
Check license (SFOS-FIREWALL-MIB).
=over 8
=item B<--filter-name>
Filter licenses by name (can be a regexp).
=item B<--warning-status>
Define the conditions to match for the status to be WARNING.
You can use the following variables: %{name}, %{status}.
=item B<--critical-status>
Define the conditions to match for the status to be CRITICAL (default: '%{status} =~ /expired/i').
You can use the following variables: %{name}, %{status}.
=item B<--unit>
Select the time unit for the expiration thresholds. May be 's' for seconds, 'm' for minutes, 'h' for hours, 'd' for days, 'w' for weeks. Default is seconds.
=item B<--warning-expires>
Threshold.
Example: C<--unit=w --warning-expires=2:> will result in a WARNING state when one of the licenses expires in less than
two weeks.
=item B<--critical-expires>
Threshold.
Example: C<--unit=w --critical-expires=2:> will result in a CRITICAL state when one of the licenses expires in less than
two weeks.
=back
=cut

View File

@ -0,0 +1,232 @@
#
# 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::cyberoam::snmp::mode::listvpns;
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-connection-status:s" => { name => 'filter_connection_status' },
"filter-vpn-activated:s" => { name => 'filter_vpn_activated' },
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
sub manage_selection {
my ($self, %options) = @_;
my $map_connection_status = {
0 => 'inactive',
1 => 'active',
2 => 'partially-active'
};
my $map_vpn_activated = {
0 => 'inactive',
1 => 'active'
};
my $map_connection_type = {
1 => 'host-to-host',
2 => 'site-to-site',
3 => 'tunnel-interface'
};
my $mapping = {
name =>
{ oid => '.1.3.6.1.4.1.2604.5.1.6.1.1.1.1.2' },# sfosIPSecVpnConnName
policy =>
{ oid => '.1.3.6.1.4.1.2604.5.1.6.1.1.1.1.4' },# sfosIPSecVpnPolicyUsed
description =>
{ oid => '.1.3.6.1.4.1.2604.5.1.6.1.1.1.1.3' },# sfosIPSecVpnConnDes
connection_mode =>
{ oid => '.1.3.6.1.4.1.2604.5.1.6.1.1.1.1.5' },# sfosIPSecVpnConnMode
connection_type =>
{ oid => '.1.3.6.1.4.1.2604.5.1.6.1.1.1.1.6', map => $map_connection_type },# sfosIPSecVpnConnType
connection_status =>
{ oid => '.1.3.6.1.4.1.2604.5.1.6.1.1.1.1.9', map => $map_connection_status },# sfosIPSecVpnConnStatus
activated =>
{ oid => '.1.3.6.1.4.1.2604.5.1.6.1.1.1.1.10', map => $map_vpn_activated }# sfosIPSecVpnActivated
};
# parent oid for all the mapping usage
my $oid_bsnAPEntry = '.1.3.6.1.4.1.2604.5.1.6.1.1.1';
my $snmp_result = $options{snmp}->get_table(
oid => $oid_bsnAPEntry,
start => $mapping->{name}->{oid},# First oid of the mapping => here : 2
end => $mapping->{activated}->{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->{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 VPN '$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_connection_status}) && $self->{option_results}->{filter_connection_status} ne '' &&
$result->{connection_status} !~ /$self->{option_results}->{filter_connection_status}/) {
$self->{output}->output_add(long_msg =>
"skipping '" . $result->{connection_status} . "': no matching connection_status filter.",
debug =>
1);
next;
}
if (defined($self->{option_results}->{filter_vpn_activated}) && $self->{option_results}->{filter_vpn_activated} ne '' &&
$result->{activated} !~ /$self->{option_results}->{filter_vpn_activated}/) {
$self->{output}->output_add(long_msg =>
"skipping '" . $result->{activated} . "': no matching activated filter.",
debug =>
1);
next;
}
$results->{$oid_path} = {
name => $result->{name},
policy => $result->{policy},
description => $result->{description},
connection_mode => $result->{connection_mode},
connection_type => $result->{connection_type},
connection_status => $result->{connection_status},
activated => $result->{activated}
};
}
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] [policy: %s] [description: %s] [connection_mode: %s] [connection_type: %s] [connection_status: %s] [activated: %s]',
$oid_path,
$results->{$oid_path}->{name},
$results->{$oid_path}->{policy},
$results->{$oid_path}->{description},
$results->{$oid_path}->{connection_mode},
$results->{$oid_path}->{connection_type},
$results->{$oid_path}->{connection_status},
$results->{$oid_path}->{activated}
)
);
}
$self->{output}->output_add(
severity => 'OK',
short_msg => 'List vpn'
);
$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', 'policy', 'description', 'connection_mode', 'connection_type', 'connection_status', 'activated' ]);
}
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},
policy =>
$results->{$oid_path}->{policy},
description =>
$results->{$oid_path}->{description},
connection_mode =>
$results->{$oid_path}->{connection_mode},
connection_type =>
$results->{$oid_path}->{connection_type},
connection_status =>
$results->{$oid_path}->{connection_status},
activated =>
$results->{$oid_path}->{activated}
);
}
}
1;
__END__
=head1 MODE
List VPN.
=over 8
=item B<--filter-name>
Display VPN matching the filter.
=item B<--filter-connection-status>
Display VPN matching the filter.
=item B<--filter-vpn-activated>
Display VPN matching the filter.
=back
=cut

View File

@ -0,0 +1,386 @@
#
# 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::cyberoam::snmp::mode::vpnstatus;
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}->{connection_status};
return $msg;
}
sub prefix_global_output {
my ($self, %options) = @_;
return 'VPN ';
}
sub vpn_long_output {
my ($self, %options) = @_;
return "checking vpn '" . $options{instance_value}->{display} . "'";
}
sub prefix_vpn_output {
my ($self, %options) = @_;
my $output = "VPN '" . $options{instance_value}->{display} . "' ";
if (defined(($options{instance_value}->{vpn_global}->{description}))
&& ($options{instance_value}->{vpn_global}->{description})) {
$output .= "($options{instance_value}->{vpn_global}->{description}) ";
}
return $output;
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{
name => 'global',
type => 0,
cb_prefix_output => 'prefix_global_output'
},
{
name => 'vpn',
type => 3,
cb_prefix_output => 'prefix_vpn_output',
cb_long_output => 'vpn_long_output',
indent_long_output => ' ',
message_multiple => 'All VPNs are ok',
group => [
{ name => 'vpn_global', type => 0 }
]
}
];
$self->{maps_counters}->{global} = [
{
label => 'total',
type => 1,
nlabel => 'vpn.total.count',
set => {
key_values => [ { name => 'total' } ],
output_template => 'total: %s',
perfdatas => [
{ label => 'total', template => '%s', min => 0 }
]
}
},
{
label => 'total-inactive',
type => 1,
nlabel => 'vpn.inactive.count',
set => {
key_values => [ { name => 'inactive' } ],
output_template => 'inactive: %s',
perfdatas => [
{ label => 'total_inactive', template => '%s', min => 0 }
]
}
},
{
label => 'total-active',
type => 1,
nlabel => 'vpn.active.count',
set => {
key_values => [ { name => 'active' } ],
output_template => 'active: %s',
perfdatas => [
{ label => 'total_active', template => '%s', min => 0 }
]
}
},
{
label => 'total-partially-active',
type => 1,
nlabel => 'vpn.partiallyactive.count',
set => {
key_values => [ { name => 'partiallyActive' } ],
output_template => 'partially active: %s',
perfdatas => [
{ label => 'total_partially_active', template => '%s', min => 0 }
]
}
}
];
$self->{maps_counters}->{vpn_global} = [
{
label => 'status',
type => 2,
critical_default => '%{connection_status} =~ /inactive/',
warning_default => '%{connection_status} =~ /partiallyActive/',
set => {
key_values => [ { name => 'connection_status' }, { name => 'display' }, { name => 'description' } ],
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-vpn-activated:s" => { name => 'filter_vpn_activated' },
"filter-connection-mode:s" => { name => 'filter_connection_mode' },
"filter-connection-type:s" => { name => 'filter_connection_type' }
});
return $self;
}
# SFOS-FIREWALL-MIB::sfosIPSecVpnConnStatus
# sfosIPSecVpnConnStatus OBJECT-TYPE
# -- FROM SFOS-FIREWALL-MIB
# -- TEXTUAL CONVENTION IPSecVPNConnectionStatus
# SYNTAX INTEGER {inactive(0), active(1), partially-active(2)}
# MAX-ACCESS read-only
# STATUS current
# DESCRIPTION "Connection status of IPsec tunnel"
# ::= { iso(1) org(3) dod(6) internet(1) private(4) enterprises(1) sophosMIB(2604) sfosXGMIB(5) sfosXGMIBObjects(1) sfosXGTunnelInfo(6) sfosVPNInfo(1) sfosIPSecVPNConnInfo(1) sfosIPSecVpnTunnelTable(1) sfosIPSecVpnTunnelEntry(1) 9 }
my $map_connection_status = {
0 => 'inactive',
1 => 'active',
2 => 'partiallyActive'
};
# SFOS-FIREWALL-MIB::sfosIPSecVpnActivated
# sfosIPSecVpnActivated OBJECT-TYPE
# -- FROM SFOS-FIREWALL-MIB
# -- TEXTUAL CONVENTION IPSecVPNActivationStatus
# SYNTAX INTEGER {inactive(0), active(1)}
# MAX-ACCESS read-only
# STATUS current
# DESCRIPTION "Activation status of IPsec tunnel"
# ::= { iso(1) org(3) dod(6) internet(1) private(4) enterprises(1) sophosMIB(2604) sfosXGMIB(5) sfosXGMIBObjects(1) sfosXGTunnelInfo(6) sfosVPNInfo(1) sfosIPSecVPNConnInfo(1) sfosIPSecVpnTunnelTable(1) sfosIPSecVpnTunnelEntry(1) 10 }
my $map_vpn_activated = {
0 => 'inactive',
1 => 'active'
};
# SFOS-FIREWALL-MIB::sfosIPSecVpnConnType
# sfosIPSecVpnConnType OBJECT-TYPE
# -- FROM SFOS-FIREWALL-MIB
# -- TEXTUAL CONVENTION IPSecVPNConnectionType
# SYNTAX INTEGER {host-to-host(1), site-to-site(2), tunnel-interface(3)}
# MAX-ACCESS read-only
# STATUS current
# DESCRIPTION "Connection Type of IPsec Tunnel"
# ::= { iso(1) org(3) dod(6) internet(1) private(4) enterprises(1) sophosMIB(2604) sfosXGMIB(5) sfosXGMIBObjects(1) sfosXGTunnelInfo(6) sfosVPNInfo(1) sfosIPSecVPNConnInfo(1) sfosIPSecVpnTunnelTable(1) sfosIPSecVpnTunnelEntry(1) 6 }
my $map_connection_type = {
1 => 'host-to-host',
2 => 'site-to-site',
3 => 'tunnel-interface'
};
my $mapping = {
name => { oid => '.1.3.6.1.4.1.2604.5.1.6.1.1.1.1.2' },# sfosIPSecVpnConnName
connection_mode => { oid => '.1.3.6.1.4.1.2604.5.1.6.1.1.1.1.5' },# sfosIPSecVpnConnMode
connection_type => { oid => '.1.3.6.1.4.1.2604.5.1.6.1.1.1.1.6', map => $map_connection_type },# sfosIPSecVpnConnType
activated => { oid => '.1.3.6.1.4.1.2604.5.1.6.1.1.1.1.10', map => $map_vpn_activated }# sfosIPSecVpnActivated
};
my $mapping_stat = {
description => { oid => '.1.3.6.1.4.1.2604.5.1.6.1.1.1.1.3' },# sfosIPSecVpnConnDes
connection_status =>
{ oid => '.1.3.6.1.4.1.2604.5.1.6.1.1.1.1.9', map => $map_connection_status }# sfosIPSecVpnConnStatus
};
sub manage_selection {
my ($self, %options) = @_;
$self->{vpn} = {};
$self->{global} = {
inactive => 0,
active => 0,
partiallyActive => 0
};
my $request = [ { oid => $mapping->{name}->{oid} } ];
push @$request, { oid => $mapping->{activated}->{oid} }
if (defined($self->{option_results}->{filter_vpn_activated}) && $self->{option_results}->{filter_vpn_activated} ne '');
push @$request, { oid => $mapping->{connection_mode}->{oid} }
if (defined($self->{option_results}->{filter_connection_mode}) && $self->{option_results}->{filter_connection_mode} ne '');
push @$request, { oid => $mapping->{connection_type}->{oid} }
if (defined($self->{option_results}->{filter_connection_type}) && $self->{option_results}->{filter_connection_type} ne '');
my $snmp_result = $options{snmp}->get_multiple_table(
oids => $request,
return_type => 1,
nothing_quit => 1
);
foreach (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($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} . "': not matching name filter.");
next;
}
if (defined($self->{option_results}->{filter_connection_type}) && $self->{option_results}->{filter_connection_type} ne '' &&
$result->{connection_type} !~ /$self->{option_results}->{filter_connection_type}/) {
$self->{output}->output_add(long_msg => "skipping '" . $result->{connection_type} . "': not matching connection-type filter.");
next;
}
if (defined($self->{option_results}->{filter_connection_mode}) && $self->{option_results}->{filter_connection_mode} ne '' &&
$result->{connection_mode} !~ /$self->{option_results}->{filter_connection_mode}/) {
$self->{output}->output_add(long_msg => "skipping '" . $result->{connection_mode} . "': not matching connection-mode filter.");
next;
}
if (defined($self->{option_results}->{filter_vpn_activated}) && $self->{option_results}->{filter_vpn_activated} ne '' &&
$result->{activated} !~ /$self->{option_results}->{filter_vpn_activated}/) {
$self->{output}->output_add(long_msg => "skipping '" . $result->{activated} . "': not matching vpn-activated filter " . $self->{option_results}->{filter_vpn_activated} . ".");
next;
}
$self->{vpn}->{ $result->{name} } = {
instance => $instance,
display => $result->{name},
vpn_global => { display => $result->{name} } };
}
if (scalar(keys %{$self->{vpn}}) <= 0) {
$self->{output}->output_add(long_msg => 'no VPN associated');
return;
}
$options{snmp}->load(
oids => [ map($_->{oid}, values(%$mapping_stat)) ],
instances => [ map($_->{instance}, values %{$self->{vpn}}) ],
instance_regexp => '^(.*)$'
);
$snmp_result = $options{snmp}->get_leef();
foreach (keys %{$self->{vpn}}) {
my $result = $options{snmp}->map_instance(
mapping => $mapping_stat,
results => $snmp_result,
instance => $self->{vpn}->{$_}->{instance});
$self->{global}->{total}++;
$self->{global}->{ $result->{connection_status} }++;
$self->{vpn}->{$_}->{vpn_global}->{connection_status} = $result->{connection_status};
$self->{vpn}->{$_}->{vpn_global}->{description} = $result->{description};
}
}
1;
__END__
=head1 MODE
Check VPN status.
VPN-Connection-Status: inactive, active, partiallyActive
=over 8
=item B<--filter-counters>
Only display some counters (regexp can be used).
Example: --filter-counters='^total$|^total-normal$'
=item B<--filter-name>
Filter VPN name (can be a regexp).
=item B<--filter-vpn-activated>
Filter by the activation status of the VPN (can be a regexp).
Values: active, inactive
=item B<--filter-connection-mode>
Filter by the connection mode of the VPN (can be a regexp).
=item B<--connection-type>
Filter by the connection type of the VPN (can be a regexp).
Values: host-to-host, site-to-site, tunnel-interface
=item B<--warning-status>
Trigger warning on %{connection_status} values.
(default: '%{connection_status} =~ /partiallyActive/').
=item B<--critical-status>
Trigger critical on %{connection_status} values.
(default: '%{connection_status} =~ /inactive/').
=item B<--warning-total>
Thresholds.
=item B<--critical-total>
Thresholds.
=item B<--warning-total-inactive>
Thresholds.
=item B<--critical-total-inactive>
Thresholds.
=item B<--warning-total-partially-active>
Thresholds.
=item B<--critical-total-partially-active>
Thresholds.
=item B<--warning-total-active>
Thresholds.
=item B<--critical-total-active>
Thresholds.
=back
=cut

View File

@ -32,12 +32,16 @@ sub new {
$self->{version} = '0.1';
$self->{modes} = {
'cpu' => 'network::cyberoam::snmp::mode::cpu',
'ha-status' => 'network::cyberoam::snmp::mode::hastatus',
'interfaces' => 'snmp_standard::mode::interfaces',
'license' => 'network::cyberoam::snmp::mode::license',
'list-interfaces' => 'snmp_standard::mode::listinterfaces',
'list-vpns' => 'network::cyberoam::snmp::mode::listvpns',
'memory' => 'network::cyberoam::snmp::mode::memory',
'requests' => 'network::cyberoam::snmp::mode::requests',
'services' => 'network::cyberoam::snmp::mode::services',
'storage' => 'network::cyberoam::snmp::mode::storage'
'storage' => 'network::cyberoam::snmp::mode::storage',
'vpn-status' => 'network::cyberoam::snmp::mode::vpnstatus'
};
return $self;

View File

@ -45,6 +45,18 @@ sub custom_expires_perfdata {
);
}
sub custom_last_update_threshold {
my ($self, %options) = @_;
return $self->{perfdata}->threshold_check(
value => floor($self->{result_values}->{last_update_seconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }),
threshold => [
{ label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' },
{ label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' }
]
);
}
sub custom_expires_threshold {
my ($self, %options) = @_;
@ -95,7 +107,17 @@ sub set_counters {
closure_custom_perfdata => $self->can('custom_expires_perfdata'),
closure_custom_threshold_check => $self->can('custom_expires_threshold')
}
},
{ label => 'last-update', set => {
key_values => [ { name => 'last_update_seconds' }, { name => 'last_update_human' }, { name => 'name' } ],
output_template => 'last_update is %s',
output_use => 'last_update_human',
#closure_custom_perfdata => $self->can('custom_expires_perfdata'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => $self->can('custom_last_update_threshold')
}
}
];
}
@ -132,6 +154,14 @@ sub add_license {
name => $options{name},
status => $options{entry}->{status}
};
if (defined($options{entry}->{last_update})) {
$self->{licenses}->{ $options{name} }->{last_update_seconds} = time() - $options{entry}->{last_update};
$self->{licenses}->{ $options{name} }->{last_update_human} = centreon::plugins::misc::change_seconds(
value => $self->{licenses}->{ $options{name} }->{last_update_seconds}
);
}
if (defined($options{entry}->{expires})) {
$self->{licenses}->{ $options{name} }->{expires_seconds} = $options{entry}->{expires} - time();
$self->{licenses}->{ $options{name} }->{expires_seconds} = 0 if ($self->{licenses}->{ $options{name} }->{expires_seconds} < 0);
@ -187,12 +217,13 @@ You can use the following variables: %{name}, %{status}.
=item B<--unit>
Select the time unit for the expiration thresholds. May be 's' for seconds, 'm' for minutes, 'h' for hours, 'd' for days, 'w' for weeks. Default is seconds.
Select the time unit for the expiration thresholds. May be 's' for seconds, 'm' for minutes, 'h' for hours, 'd' for days, 'w' for weeks.
Default is seconds.
=item B<--warning-*> B<--critical-*>
Thresholds.
Can be: 'expires'.
Can be: 'expires', 'last-update'
=back

View File

@ -0,0 +1,201 @@
#
# Copyright 2025 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package network::moxa::switch::snmp::mode::interfaces;
use base qw(snmp_standard::mode::interfaces);
use strict;
use warnings;
sub set_oids_status {
my ($self, %options) = @_;
$self->SUPER::set_oids_status(%options);
# Standard duplex oid don't work on moxa industrial switches (eds405a)
$self->{oid_duplexstatus} = '.1.3.6.1.4.1.8691.7.6.1.10.3.1.3';
# Moxa provide a specific oid for speed/duplex, with this values definition:
# speed100M-Full(3),
# speed100M-Half(2),
# speed10M-Full(1),
# speed10M-Half(0),
# na(-1)
$self->{oid_duplexstatus_mapping} = {
-1 => 'unknown', 0 => 'halfDuplex', 2 => 'halfDuplex', 3 => 'fullDuplex',1 => 'fullDuplex'
};
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
return $self;
}
1;
__END__
=head1 MODE
Check interfaces of moxa industrial switches.
=over 8
=item B<--add-global>
Check global port statistics (by default if no --add-* option is set).
=item B<--add-status>
Check interface status.
=item B<--add-duplex-status>
Check duplex status (with --warning-status and --critical-status).
=item B<--add-traffic>
Check interface traffic.
=item B<--add-errors>
Check interface errors.
=item B<--add-cast>
Check interface cast.
=item B<--add-speed>
Check interface speed.
=item B<--add-volume>
Check interface data volume between two checks (not supposed to be graphed, useful for BI reporting).
=item B<--check-metrics>
If the expression is true, metrics are checked (default: '%{opstatus} eq "up"').
=item B<--warning-status>
Define the conditions to match for the status to be WARNING.
You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display}
=item B<--critical-status>
Define the conditions to match for the status to be CRITICAL (default: '%{admstatus} eq "up" and %{opstatus} ne "up"').
You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display}
=item B<--warning-*> B<--critical-*>
Thresholds.
Can be: 'total-port', 'total-admin-up', 'total-admin-down', 'total-oper-up', 'total-oper-down',
'in-traffic', 'out-traffic', 'in-error', 'in-discard', 'out-error', 'out-discard',
'in-ucast', 'in-bcast', 'in-mcast', 'out-ucast', 'out-bcast', 'out-mcast',
'speed' (b/s).
=item B<--units-traffic>
Units of thresholds for the traffic (default: 'percent_delta') ('percent_delta', 'bps', 'counter').
=item B<--units-errors>
Units of thresholds for errors/discards (default: 'percent_delta') ('percent_delta', 'percent', 'delta', 'deltaps', 'counter').
=item B<--units-cast>
Units of thresholds for communication types (default: 'percent_delta') ('percent_delta', 'percent', 'delta', 'deltaps', 'counter').
=item B<--nagvis-perfdata>
Display traffic perfdata to be compatible with NagVis widget.
=item B<--interface>
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>
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>
Set interface speed for incoming/outgoing traffic (in Mb).
=item B<--speed-in>
Set interface speed for incoming traffic (in Mb).
=item B<--speed-out>
Set interface speed for outgoing traffic (in Mb).
=item B<--map-speed-dsl>
Get interface speed configuration for interfaces of type 'ADSL' and 'VDSL2'.
Syntax: --map-speed-dsl=interface-src-name,interface-dsl-name
E.g: --map-speed-dsl=Et0.835,Et0-vdsl2
=item B<--force-counters64>
Force to use 64 bits counters only. Can be used to improve performance.
=item B<--force-counters32>
Force to use 32-bit counters (even with SNMP versions 2c and 3). To use when 64 bits counters are buggy.
=item B<--reload-cache-time>
Time in minutes before reloading cache file (default: 180).
=item B<--oid-filter>
Define the OID to be used to filter interfaces (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr).
=item B<--oid-display>
Define the OID that will be used to name the interfaces (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr).
=item B<--oid-extra-display>
Add an OID to display.
=item B<--display-transform-src> B<--display-transform-dst>
Modify the interface name displayed by using a regular expression.
Example: adding --display-transform-src='eth' --display-transform-dst='ens' will replace all occurrences of 'eth' with 'ens'
=item B<--show-cache>
Display cache interface data.
=back
=cut

View File

@ -32,7 +32,7 @@ sub new {
$self->{version} = '0.1';
%{$self->{modes}} = (
'cpu' => 'network::moxa::switch::snmp::mode::cpu',
'interfaces' => 'snmp_standard::mode::interfaces',
'interfaces' => 'network::moxa::switch::snmp::mode::interfaces',
'list-interfaces' => 'snmp_standard::mode::listinterfaces',
'memory' => 'network::moxa::switch::snmp::mode::memory',
'uptime' => 'snmp_standard::mode::uptime',

View File

@ -2,7 +2,7 @@
## Robot tests
In this project robot is used to order the integration tests.
In this project robot Framework is used to order the integration tests.
### install snmpsim
@ -30,6 +30,21 @@ robot tests/
you can filter the tests run by specifying -e to exclude and -i to include a specific tag before the file path.
## Get new data
### Http
Any `curl -v` command should give enough info to create new tests/plugins on new http services.
If the plugin already exists, you can use the plugin to gater the data with the `--debug --verbose` options.
### Snmp
To get snmp data, you can use the snmpwalk command on the host you want to monitor.
```bash
snmpwalk -ObentU -v2c -c 'public' localhost .1
```
## Anonymize tests
@ -40,7 +55,6 @@ the option `--no-anonymization` allow to not anonymize the data and only remove
perl ./tests/scripts/slim_walk.pl --snmpwalk-path=tests/hardware/client.snmpwalk > smaller-file.snmpwalk
```
## unit tests
In this project perl test::v0 is used to run unit tests.

View File

@ -0,0 +1,45 @@
*** Settings ***
Documentation HAProxy Backend Usage Monitoring
Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}mockoon.json
${cmd} ${CENTREON_PLUGINS}
... --plugin=apps::haproxy::web::plugin
... --mode=backend-usage
... --hostname=${HOSTNAME}
... --username='username'
... --password='password'
... --proto='http'
... --port=${APIPORT}
*** Test Cases ***
backend-usage ${tc}
[Tags] mockoon restapi
${command} Catenate
... ${CMD}
... --filter-name='${filter_name}'
... ${extra_options}
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc filter_name extra_options expected_result --
... 1 STATIC_BG_IMAGE ${EMPTY} OK: Backend 'STATIC_BG_IMAGE' backend status: UP, current queue: 0, current session rate: 0/s, max session rate: 1/s, current sessions: 0, backend-total-sessions : Buffer creation, backend-traffic-in : Buffer creation, backend-traffic-out : Buffer creation, denied requests: 0, denied responses: 0, connection errors: 0, responses errors: 0 | 'STATIC_BG_IMAGE#backend.queue.current.count'=0;;;0; 'STATIC_BG_IMAGE#backend.session.current.rate.countpersecond'=0;;;0; 'STATIC_BG_IMAGE#backend.session.max.rate.countpersecond'=1;;;0; 'STATIC_BG_IMAGE#backend.sessions.current.count'=0;;;0; 'STATIC_BG_IMAGE#backend.requests.denied.count'=0;;;0; 'STATIC_BG_IMAGE#backend.responses.denied.count'=0;;;0; 'STATIC_BG_IMAGE#backend.connections.error.count'=0;;;0; 'STATIC_BG_IMAGE#backend.responses.error.count'=0;;;0;
... 2 STATIC_BG_IMAGE --warning-backend-max-session-rate=0:0 WARNING: Backend 'STATIC_BG_IMAGE' backend max session rate: 1/s | 'STATIC_BG_IMAGE#backend.queue.current.count'=0;;;0; 'STATIC_BG_IMAGE#backend.session.current.rate.countpersecond'=0;;;0; 'STATIC_BG_IMAGE#backend.session.max.rate.countpersecond'=1;0:0;;0; 'STATIC_BG_IMAGE#backend.sessions.current.count'=0;;;0; 'STATIC_BG_IMAGE#backend.sessions.total.count'=0;;;0; 'STATIC_BG_IMAGE#backend.traffic.in.bitpersecond'=0.00b/s;;;0; 'STATIC_BG_IMAGE#backend.traffic.out.bitpersecond'=0.00b/s;;;0; 'STATIC_BG_IMAGE#backend.requests.denied.count'=0;;;0; 'STATIC_BG_IMAGE#backend.responses.denied.count'=0;;;0; 'STATIC_BG_IMAGE#backend.connections.error.count'=0;;;0; 'STATIC_BG_IMAGE#backend.responses.error.count'=0;;;0;
... 3 STATIC_BG_IMAGE --critical-backend-max-session-rate=0:0 CRITICAL: Backend 'STATIC_BG_IMAGE' backend max session rate: 1/s | 'STATIC_BG_IMAGE#backend.queue.current.count'=0;;;0; 'STATIC_BG_IMAGE#backend.session.current.rate.countpersecond'=0;;;0; 'STATIC_BG_IMAGE#backend.session.max.rate.countpersecond'=1;;0:0;0; 'STATIC_BG_IMAGE#backend.sessions.current.count'=0;;;0; 'STATIC_BG_IMAGE#backend.sessions.total.count'=0;;;0; 'STATIC_BG_IMAGE#backend.traffic.in.bitpersecond'=0.00b/s;;;0; 'STATIC_BG_IMAGE#backend.traffic.out.bitpersecond'=0.00b/s;;;0; 'STATIC_BG_IMAGE#backend.requests.denied.count'=0;;;0; 'STATIC_BG_IMAGE#backend.responses.denied.count'=0;;;0; 'STATIC_BG_IMAGE#backend.connections.error.count'=0;;;0; 'STATIC_BG_IMAGE#backend.responses.error.count'=0;;;0;
... 4 APP-IHM ${EMPTY} OK: Backend 'APP-IHM' backend status: UP, current queue: 0, current session rate: 1/s, max session rate: 25/s, current sessions: 0, backend-total-sessions : Buffer creation, backend-traffic-in : Buffer creation, backend-traffic-out : Buffer creation, denied requests: 0, denied responses: 0, connection errors: 1, responses errors: 0 | 'APP-IHM#backend.queue.current.count'=0;;;0; 'APP-IHM#backend.session.current.rate.countpersecond'=1;;;0; 'APP-IHM#backend.session.max.rate.countpersecond'=25;;;0; 'APP-IHM#backend.sessions.current.count'=0;;;0; 'APP-IHM#backend.requests.denied.count'=0;;;0; 'APP-IHM#backend.responses.denied.count'=0;;;0; 'APP-IHM#backend.connections.error.count'=1;;;0; 'APP-IHM#backend.responses.error.count'=0;;;0;
... 5 APP-IHM --warning-backend-current-session-rate=0:0 WARNING: Backend 'APP-IHM' backend current session rate: 1/s | 'APP-IHM#backend.queue.current.count'=0;;;0; 'APP-IHM#backend.session.current.rate.countpersecond'=1;0:0;;0; 'APP-IHM#backend.session.max.rate.countpersecond'=25;;;0; 'APP-IHM#backend.sessions.current.count'=0;;;0; 'APP-IHM#backend.sessions.total.count'=0;;;0; 'APP-IHM#backend.traffic.in.bitpersecond'=0.00b/s;;;0; 'APP-IHM#backend.traffic.out.bitpersecond'=0.00b/s;;;0; 'APP-IHM#backend.requests.denied.count'=0;;;0; 'APP-IHM#backend.responses.denied.count'=0;;;0; 'APP-IHM#backend.connections.error.count'=1;;;0; 'APP-IHM#backend.responses.error.count'=0;;;0;
... 6 APP-IHM --critical-backend-current-session-rate=0:0 CRITICAL: Backend 'APP-IHM' backend current session rate: 1/s | 'APP-IHM#backend.queue.current.count'=0;;;0; 'APP-IHM#backend.session.current.rate.countpersecond'=1;;0:0;0; 'APP-IHM#backend.session.max.rate.countpersecond'=25;;;0; 'APP-IHM#backend.sessions.current.count'=0;;;0; 'APP-IHM#backend.sessions.total.count'=0;;;0; 'APP-IHM#backend.traffic.in.bitpersecond'=0.00b/s;;;0; 'APP-IHM#backend.traffic.out.bitpersecond'=0.00b/s;;;0; 'APP-IHM#backend.requests.denied.count'=0;;;0; 'APP-IHM#backend.responses.denied.count'=0;;;0; 'APP-IHM#backend.connections.error.count'=1;;;0; 'APP-IHM#backend.responses.error.count'=0;;;0;
... 7 APP-RIA ${EMPTY} OK: Backend 'APP-RIA' backend status: UP, current queue: 0, current session rate: 0/s, max session rate: 0/s, current sessions: 0, backend-total-sessions : Buffer creation, backend-traffic-in : Buffer creation, backend-traffic-out : Buffer creation, denied requests: 0, denied responses: 0, connection errors: 0, responses errors: 0 | 'APP-RIA#backend.queue.current.count'=0;;;0; 'APP-RIA#backend.session.current.rate.countpersecond'=0;;;0; 'APP-RIA#backend.session.max.rate.countpersecond'=0;;;0; 'APP-RIA#backend.sessions.current.count'=0;;;0; 'APP-RIA#backend.requests.denied.count'=0;;;0; 'APP-RIA#backend.responses.denied.count'=0;;;0; 'APP-RIA#backend.connections.error.count'=0;;;0; 'APP-RIA#backend.responses.error.count'=0;;;0;
... 8 APP-RIA --warning-backend-denied-requests=1:1 WARNING: Backend 'APP-RIA' backend denied requests: 0 | 'APP-RIA#backend.queue.current.count'=0;;;0; 'APP-RIA#backend.session.current.rate.countpersecond'=0;;;0; 'APP-RIA#backend.session.max.rate.countpersecond'=0;;;0; 'APP-RIA#backend.sessions.current.count'=0;;;0; 'APP-RIA#backend.sessions.total.count'=0;;;0; 'APP-RIA#backend.traffic.in.bitpersecond'=0.00b/s;;;0; 'APP-RIA#backend.traffic.out.bitpersecond'=0.00b/s;;;0; 'APP-RIA#backend.requests.denied.count'=0;1:1;;0; 'APP-RIA#backend.responses.denied.count'=0;;;0; 'APP-RIA#backend.connections.error.count'=0;;;0; 'APP-RIA#backend.responses.error.count'=0;;;0;
... 9 APP-RIA --critical-backend-denied-requests=1:1 CRITICAL: Backend 'APP-RIA' backend denied requests: 0 | 'APP-RIA#backend.queue.current.count'=0;;;0; 'APP-RIA#backend.session.current.rate.countpersecond'=0;;;0; 'APP-RIA#backend.session.max.rate.countpersecond'=0;;;0; 'APP-RIA#backend.sessions.current.count'=0;;;0; 'APP-RIA#backend.sessions.total.count'=0;;;0; 'APP-RIA#backend.traffic.in.bitpersecond'=0.00b/s;;;0; 'APP-RIA#backend.traffic.out.bitpersecond'=0.00b/s;;;0; 'APP-RIA#backend.requests.denied.count'=0;;1:1;0; 'APP-RIA#backend.responses.denied.count'=0;;;0; 'APP-RIA#backend.connections.error.count'=0;;;0; 'APP-RIA#backend.responses.error.count'=0;;;0;

View File

@ -0,0 +1,50 @@
*** Settings ***
Documentation HAProxy Frontend Usage Monitoring
Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}mockoon.json
${cmd} ${CENTREON_PLUGINS}
... --plugin=apps::haproxy::web::plugin
... --mode=frontend-usage
... --hostname=${HOSTNAME}
... --username='username'
... --password='password'
... --proto='http'
... --port=${APIPORT}
*** Test Cases ***
frontend-usage ${tc}
[Tags] mockoon restapi
${command} Catenate
... ${CMD}
... --filter-name='${filter_name}'
... ${extra_options}
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc filter_name extra_options expected_result --
... 1 ${EMPTY} ${EMPTY} OK: Frontend 'hafrontend' frontend status: OPEN, current session rate: 1/s, max session rate: 6/s, current sessions: 10, total sessions: 3980, max sessions: 16, frontend-traffic-in : Buffer creation, frontend-traffic-out : Buffer creation, denied requests: 0, denied responses: 0, error requests: 42 | 'hafrontend#frontend.session.current.rate.countpersecond'=1;;;0; 'hafrontend#frontend.session.max.rate.countpersecond'=6;;;0; 'hafrontend#frontend.sessions.current.count'=10;;;0; 'hafrontend#frontend.sessions.total.count'=3980;;;0; 'hafrontend#frontend.sessions.maximum.count'=16;;;0; 'hafrontend#frontend.requests.denied.count'=0;;;0; 'hafrontend#frontend.responses.denied.count'=0;;;0; 'hafrontend#frontend.requests.error.count'=42;;;0;
... 2 hafrontend ${EMPTY} OK: Frontend 'hafrontend' frontend status: OPEN, current session rate: 1/s, max session rate: 6/s, current sessions: 10, total sessions: 3980, max sessions: 16, frontend-traffic-in : Buffer creation, frontend-traffic-out : Buffer creation, denied requests: 0, denied responses: 0, error requests: 42 | 'hafrontend#frontend.session.current.rate.countpersecond'=1;;;0; 'hafrontend#frontend.session.max.rate.countpersecond'=6;;;0; 'hafrontend#frontend.sessions.current.count'=10;;;0; 'hafrontend#frontend.sessions.total.count'=3980;;;0; 'hafrontend#frontend.sessions.maximum.count'=16;;;0; 'hafrontend#frontend.requests.denied.count'=0;;;0; 'hafrontend#frontend.responses.denied.count'=0;;;0; 'hafrontend#frontend.requests.error.count'=42;;;0;
... 3 none ${EMPTY} UNKNOWN: No Frontend found.
... 4 hafrontend --warning-frontend-current-session-rate=0:0 WARNING: Frontend 'hafrontend' frontend current session rate: 1/s | 'hafrontend#frontend.session.current.rate.countpersecond'=1;0:0;;0; 'hafrontend#frontend.session.max.rate.countpersecond'=6;;;0; 'hafrontend#frontend.sessions.current.count'=10;;;0; 'hafrontend#frontend.sessions.total.count'=3980;;;0; 'hafrontend#frontend.sessions.maximum.count'=16;;;0; 'hafrontend#frontend.traffic.in.bitpersecond'=0.00b/s;;;0; 'hafrontend#frontend.traffic.out.bitpersecond'=0.00b/s;;;0; 'hafrontend#frontend.requests.denied.count'=0;;;0; 'hafrontend#frontend.responses.denied.count'=0;;;0; 'hafrontend#frontend.requests.error.count'=42;;;0;
... 5 hafrontend --critical-frontend-current-session-rate=0:0 CRITICAL: Frontend 'hafrontend' frontend current session rate: 1/s | 'hafrontend#frontend.session.current.rate.countpersecond'=1;;0:0;0; 'hafrontend#frontend.session.max.rate.countpersecond'=6;;;0; 'hafrontend#frontend.sessions.current.count'=10;;;0; 'hafrontend#frontend.sessions.total.count'=3980;;;0; 'hafrontend#frontend.sessions.maximum.count'=16;;;0; 'hafrontend#frontend.traffic.in.bitpersecond'=0.00b/s;;;0; 'hafrontend#frontend.traffic.out.bitpersecond'=0.00b/s;;;0; 'hafrontend#frontend.requests.denied.count'=0;;;0; 'hafrontend#frontend.responses.denied.count'=0;;;0; 'hafrontend#frontend.requests.error.count'=42;;;0;
... 6 hafrontend --warning-frontend-max-session-rate=0:0 WARNING: Frontend 'hafrontend' frontend max session rate: 6/s | 'hafrontend#frontend.session.current.rate.countpersecond'=1;;;0; 'hafrontend#frontend.session.max.rate.countpersecond'=6;0:0;;0; 'hafrontend#frontend.sessions.current.count'=10;;;0; 'hafrontend#frontend.sessions.total.count'=3980;;;0; 'hafrontend#frontend.sessions.maximum.count'=16;;;0; 'hafrontend#frontend.traffic.in.bitpersecond'=0.00b/s;;;0; 'hafrontend#frontend.traffic.out.bitpersecond'=0.00b/s;;;0; 'hafrontend#frontend.requests.denied.count'=0;;;0; 'hafrontend#frontend.responses.denied.count'=0;;;0; 'hafrontend#frontend.requests.error.count'=42;;;0;
... 7 hafrontend --critical-frontend-max-session-rate=0:0 CRITICAL: Frontend 'hafrontend' frontend max session rate: 6/s | 'hafrontend#frontend.session.current.rate.countpersecond'=1;;;0; 'hafrontend#frontend.session.max.rate.countpersecond'=6;;0:0;0; 'hafrontend#frontend.sessions.current.count'=10;;;0; 'hafrontend#frontend.sessions.total.count'=3980;;;0; 'hafrontend#frontend.sessions.maximum.count'=16;;;0; 'hafrontend#frontend.traffic.in.bitpersecond'=0.00b/s;;;0; 'hafrontend#frontend.traffic.out.bitpersecond'=0.00b/s;;;0; 'hafrontend#frontend.requests.denied.count'=0;;;0; 'hafrontend#frontend.responses.denied.count'=0;;;0; 'hafrontend#frontend.requests.error.count'=42;;;0;
... 8 hafrontend --warning-frontend-current-sessions=0:0 WARNING: Frontend 'hafrontend' frontend current sessions: 10 | 'hafrontend#frontend.session.current.rate.countpersecond'=1;;;0; 'hafrontend#frontend.session.max.rate.countpersecond'=6;;;0; 'hafrontend#frontend.sessions.current.count'=10;0:0;;0; 'hafrontend#frontend.sessions.total.count'=3980;;;0; 'hafrontend#frontend.sessions.maximum.count'=16;;;0; 'hafrontend#frontend.traffic.in.bitpersecond'=0.00b/s;;;0; 'hafrontend#frontend.traffic.out.bitpersecond'=0.00b/s;;;0; 'hafrontend#frontend.requests.denied.count'=0;;;0; 'hafrontend#frontend.responses.denied.count'=0;;;0; 'hafrontend#frontend.requests.error.count'=42;;;0;
... 9 hafrontend --critical-frontend-current-sessions=0:0 CRITICAL: Frontend 'hafrontend' frontend current sessions: 10 | 'hafrontend#frontend.session.current.rate.countpersecond'=1;;;0; 'hafrontend#frontend.session.max.rate.countpersecond'=6;;;0; 'hafrontend#frontend.sessions.current.count'=10;;0:0;0; 'hafrontend#frontend.sessions.total.count'=3980;;;0; 'hafrontend#frontend.sessions.maximum.count'=16;;;0; 'hafrontend#frontend.traffic.in.bitpersecond'=0.00b/s;;;0; 'hafrontend#frontend.traffic.out.bitpersecond'=0.00b/s;;;0; 'hafrontend#frontend.requests.denied.count'=0;;;0; 'hafrontend#frontend.responses.denied.count'=0;;;0; 'hafrontend#frontend.requests.error.count'=42;;;0;
... 10 hafrontend --warning-frontend-total-sessions=0:0 WARNING: Frontend 'hafrontend' frontend total sessions: 3980 | 'hafrontend#frontend.session.current.rate.countpersecond'=1;;;0; 'hafrontend#frontend.session.max.rate.countpersecond'=6;;;0; 'hafrontend#frontend.sessions.current.count'=10;;;0; 'hafrontend#frontend.sessions.total.count'=3980;0:0;;0; 'hafrontend#frontend.sessions.maximum.count'=16;;;0; 'hafrontend#frontend.traffic.in.bitpersecond'=0.00b/s;;;0; 'hafrontend#frontend.traffic.out.bitpersecond'=0.00b/s;;;0; 'hafrontend#frontend.requests.denied.count'=0;;;0; 'hafrontend#frontend.responses.denied.count'=0;;;0; 'hafrontend#frontend.requests.error.count'=42;;;0;
... 11 hafrontend --critical-frontend-total-sessions=0:0 CRITICAL: Frontend 'hafrontend' frontend total sessions: 3980 | 'hafrontend#frontend.session.current.rate.countpersecond'=1;;;0; 'hafrontend#frontend.session.max.rate.countpersecond'=6;;;0; 'hafrontend#frontend.sessions.current.count'=10;;;0; 'hafrontend#frontend.sessions.total.count'=3980;;0:0;0; 'hafrontend#frontend.sessions.maximum.count'=16;;;0; 'hafrontend#frontend.traffic.in.bitpersecond'=0.00b/s;;;0; 'hafrontend#frontend.traffic.out.bitpersecond'=0.00b/s;;;0; 'hafrontend#frontend.requests.denied.count'=0;;;0; 'hafrontend#frontend.responses.denied.count'=0;;;0; 'hafrontend#frontend.requests.error.count'=42;;;0;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,62 @@
*** Settings ***
Documentation Test the Podman container-usage mode
Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}podman.json
${cmd} ${CENTREON_PLUGINS}
... --plugin=apps::podman::restapi::plugin
... --custommode=api
... --mode=container-usage
... --hostname=${HOSTNAME}
... --port=${APIPORT}
... --proto=http
*** Test Cases ***
Container usage ${tc}
[Documentation] Check the container usage
[Tags] apps podman restapi
${command} Catenate
... ${cmd}
... --container-name=wordpress
... ${extraoptions}
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc extraoptions expected_result --
... 1 ${EMPTY} OK: CPU: 0.11%, Memory: 10.85MB, Read : 435.65MB, Write : 941.43MB, Network in: 1006.00B, Network out: 2.10KB, State: running | 'podman.container.cpu.usage.percent'=0.11%;;;0;100 'podman.container.memory.usage.bytes'=11374592B;;;0; 'podman.container.io.read'=456812354B;;;0; 'podman.container.io.write'=987156423B;;;0; 'podman.container.network.in'=1006B;;;0; 'podman.container.network.out'=2146B;;;0;
... 2 --warning-cpu-usage=0.1 WARNING: CPU: 0.11% | 'podman.container.cpu.usage.percent'=0.11%;0:0.1;;0;100 'podman.container.memory.usage.bytes'=11374592B;;;0; 'podman.container.io.read'=456812354B;;;0; 'podman.container.io.write'=987156423B;;;0; 'podman.container.network.in'=1006B;;;0; 'podman.container.network.out'=2146B;;;0;
... 3 --critical-cpu-usage=0.1 CRITICAL: CPU: 0.11% | 'podman.container.cpu.usage.percent'=0.11%;;0:0.1;0;100 'podman.container.memory.usage.bytes'=11374592B;;;0; 'podman.container.io.read'=456812354B;;;0; 'podman.container.io.write'=987156423B;;;0; 'podman.container.network.in'=1006B;;;0; 'podman.container.network.out'=2146B;;;0;
... 4 --warning-memory-usage=10000000 WARNING: Memory: 10.85MB | 'podman.container.cpu.usage.percent'=0.11%;;;0;100 'podman.container.memory.usage.bytes'=11374592B;0:10000000;;0; 'podman.container.io.read'=456812354B;;;0; 'podman.container.io.write'=987156423B;;;0; 'podman.container.network.in'=1006B;;;0; 'podman.container.network.out'=2146B;;;0;
... 5 --critical-memory-usage=10000000 CRITICAL: Memory: 10.85MB | 'podman.container.cpu.usage.percent'=0.11%;;;0;100 'podman.container.memory.usage.bytes'=11374592B;;0:10000000;0; 'podman.container.io.read'=456812354B;;;0; 'podman.container.io.write'=987156423B;;;0; 'podman.container.network.in'=1006B;;;0; 'podman.container.network.out'=2146B;;;0;
... 6 --warning-read-io=200000000 WARNING: Read : 435.65MB | 'podman.container.cpu.usage.percent'=0.11%;;;0;100 'podman.container.memory.usage.bytes'=11374592B;;;0; 'podman.container.io.read'=456812354B;0:200000000;;0; 'podman.container.io.write'=987156423B;;;0; 'podman.container.network.in'=1006B;;;0; 'podman.container.network.out'=2146B;;;0;
... 7 --critical-read-io=400000000 CRITICAL: Read : 435.65MB | 'podman.container.cpu.usage.percent'=0.11%;;;0;100 'podman.container.memory.usage.bytes'=11374592B;;;0; 'podman.container.io.read'=456812354B;;0:400000000;0; 'podman.container.io.write'=987156423B;;;0; 'podman.container.network.in'=1006B;;;0; 'podman.container.network.out'=2146B;;;0;
... 8 --warning-write-io=500000000 WARNING: Write : 941.43MB | 'podman.container.cpu.usage.percent'=0.11%;;;0;100 'podman.container.memory.usage.bytes'=11374592B;;;0; 'podman.container.io.read'=456812354B;;;0; 'podman.container.io.write'=987156423B;0:500000000;;0; 'podman.container.network.in'=1006B;;;0; 'podman.container.network.out'=2146B;;;0;
... 9 --critical-write-io=750000000 CRITICAL: Write : 941.43MB | 'podman.container.cpu.usage.percent'=0.11%;;;0;100 'podman.container.memory.usage.bytes'=11374592B;;;0; 'podman.container.io.read'=456812354B;;;0; 'podman.container.io.write'=987156423B;;0:750000000;0; 'podman.container.network.in'=1006B;;;0; 'podman.container.network.out'=2146B;;;0;
Container usage ${tc}
[Documentation] Check the container usage
[Tags] apps podman restapi
${command} Catenate
... ${cmd}
... --container-name=wordpress
... ${extraoptions}
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc extraoptions expected_result --
... 10 --warning-network-in=500 WARNING: Network in: 1006.00B | 'podman.container.cpu.usage.percent'=0.11%;;;0;100 'podman.container.memory.usage.bytes'=11374592B;;;0; 'podman.container.io.read'=456812354B;;;0; 'podman.container.io.write'=987156423B;;;0; 'podman.container.network.in'=1006B;0:500;;0; 'podman.container.network.out'=2146B;;;0;
... 11 --critical-network-in=1000 CRITICAL: Network in: 1006.00B | 'podman.container.cpu.usage.percent'=0.11%;;;0;100 'podman.container.memory.usage.bytes'=11374592B;;;0; 'podman.container.io.read'=456812354B;;;0; 'podman.container.io.write'=987156423B;;;0; 'podman.container.network.in'=1006B;;0:1000;0; 'podman.container.network.out'=2146B;;;0;
... 12 --warning-network-out=1000 WARNING: Network out: 2.10KB | 'podman.container.cpu.usage.percent'=0.11%;;;0;100 'podman.container.memory.usage.bytes'=11374592B;;;0; 'podman.container.io.read'=456812354B;;;0; 'podman.container.io.write'=987156423B;;;0; 'podman.container.network.in'=1006B;;;0; 'podman.container.network.out'=2146B;0:1000;;0;
... 13 --critical-network-out=2000 CRITICAL: Network out: 2.10KB | 'podman.container.cpu.usage.percent'=0.11%;;;0;100 'podman.container.memory.usage.bytes'=11374592B;;;0; 'podman.container.io.read'=456812354B;;;0; 'podman.container.io.write'=987156423B;;;0; 'podman.container.network.in'=1006B;;;0; 'podman.container.network.out'=2146B;;0:2000;0;
... 14 --warning-state='\\\%{state} =~ /running/' WARNING: State: running | 'podman.container.cpu.usage.percent'=0.11%;;;0;100 'podman.container.memory.usage.bytes'=11374592B;;;0; 'podman.container.io.read'=456812354B;;;0; 'podman.container.io.write'=987156423B;;;0; 'podman.container.network.in'=1006B;;;0; 'podman.container.network.out'=2146B;;;0;
... 15 --critical-state='\\\%{state} =~ /running/' CRITICAL: State: running | 'podman.container.cpu.usage.percent'=0.11%;;;0;100 'podman.container.memory.usage.bytes'=11374592B;;;0; 'podman.container.io.read'=456812354B;;;0; 'podman.container.io.write'=987156423B;;;0; 'podman.container.network.in'=1006B;;;0; 'podman.container.network.out'=2146B;;;0;

View File

@ -0,0 +1,36 @@
*** Settings ***
Documentation Test the Podman list-containers mode
Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}podman.json
${cmd} ${CENTREON_PLUGINS}
... --plugin=apps::podman::restapi::plugin
... --custommode=api
... --mode=list-containers
... --hostname=${HOSTNAME}
... --port=${APIPORT}
... --proto=http
*** Test Cases ***
List-Containers ${tc}
[Documentation] Check list-containers results
[Tags] apps podman restapi
${command} Catenate
... ${cmd}
... ${extraoptions}
Ctn Run Command And Check Result As Regexp ${command} ${expected_result}
Examples: tc extraoptions expected_result --
... 1 ${EMPTY} ^Containers: (\\\\n\\\\[.*\\\\]){3}\\\\Z
... 2 --disco-show \\\\<\\\\?xml version="1.0" encoding="utf-8"\\\\?\\\\>\\\\n\\\\<data\\\\>(\\\\n\\\\s*\\\\<label .*\\\\/\\\\>){3}\\\\n\\\\<\\\\/data\\\\>
... 3 --disco-format \\\\<\\\\?xml version="1.0" encoding="utf-8"\\\\?\\\\>\\\\n\\\\<data\\\\>(\\\\n\\\\s*\\\\<element\\\\>.*\\\\<\\\\/element\\\\>){4}\\\\n\\\\<\\\\/data\\\\>

View File

@ -0,0 +1,36 @@
*** Settings ***
Documentation Test the Podman list-pods mode
Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}podman.json
${cmd} ${CENTREON_PLUGINS}
... --plugin=apps::podman::restapi::plugin
... --custommode=api
... --mode=list-pods
... --hostname=${HOSTNAME}
... --port=${APIPORT}
... --proto=http
*** Test Cases ***
List-Pods ${tc}
[Documentation] Check list-pods results
[Tags] apps podman restapi
${command} Catenate
... ${cmd}
... ${extraoptions}
Ctn Run Command And Check Result As Regexp ${command} ${expected_result}
Examples: tc extraoptions expected_result --
... 1 ${EMPTY} ^Pods: (\\\\n\\\\[.*\\\\]){2}\\\\Z
... 2 --disco-show \\\\<\\\\?xml version="1.0" encoding="utf-8"\\\\?\\\\>\\\\n\\\\<data\\\\>(\\\\n\\\\s*\\\\<label .*\\\\/\\\\>){2}\\\\n\\\\<\\\\/data\\\\>
... 3 --disco-format \\\\<\\\\?xml version="1.0" encoding="utf-8"\\\\?\\\\>\\\\n\\\\<data\\\\>(\\\\n\\\\s*\\\\<element\\\\>.*\\\\<\\\\/element\\\\>){3}\\\\n\\\\<\\\\/data\\\\>

View File

@ -0,0 +1,257 @@
{
"uuid": "213bb6ee-47d9-4256-a740-ee7472fb871a",
"lastMigration": 32,
"name": "Podman",
"endpointPrefix": "",
"latency": 0,
"port": 3000,
"hostname": "",
"folders": [],
"routes": [
{
"uuid": "f390a04c-57ee-49dc-a35a-62b296e75cdb",
"type": "http",
"documentation": "",
"method": "get",
"endpoint": "v5.0.0/libpod/info",
"responses": [
{
"uuid": "b885b4f3-683d-4974-b055-e64505c73b97",
"body": "{\n \"host\": {\n \"arch\": \"amd64\",\n \"buildahVersion\": \"1.28.2\",\n \"cgroupManager\": \"systemd\",\n \"cgroupVersion\": \"v2\",\n \"cgroupControllers\": [\n \"cpu\",\n \"memory\",\n \"pids\"\n ],\n \"conmon\": {\n \"package\": \"conmon_2.1.6+ds1-1_amd64\",\n \"path\": \"/usr/bin/conmon\",\n \"version\": \"conmon version 2.1.6, commit: unknown\"\n },\n \"cpus\": 2,\n \"cpuUtilization\": {\n \"userPercent\": 0.11,\n \"systemPercent\": 1.08,\n \"idlePercent\": 98.81\n },\n \"distribution\": {\n \"distribution\": \"debian\",\n \"version\": \"12\",\n \"codename\": \"bookworm\"\n },\n \"eventLogger\": \"journald\",\n \"hostname\": \"deb12\",\n \"idMappings\": {\n \"gidmap\": [\n {\n \"container_id\": 0,\n \"host_id\": 1000,\n \"size\": 1\n },\n {\n \"container_id\": 1,\n \"host_id\": 100000,\n \"size\": 65536\n }\n ],\n \"uidmap\": [\n {\n \"container_id\": 0,\n \"host_id\": 1000,\n \"size\": 1\n },\n {\n \"container_id\": 1,\n \"host_id\": 100000,\n \"size\": 65536\n }\n ]\n },\n \"kernel\": \"6.1.0-15-amd64\",\n \"logDriver\": \"journald\",\n \"memFree\": 82362368,\n \"memTotal\": 2062614528,\n \"networkBackend\": \"netavark\",\n \"ociRuntime\": {\n \"name\": \"crun\",\n \"package\": \"crun_1.8.1-1+deb12u1_amd64\",\n \"path\": \"/usr/bin/crun\",\n \"version\": \"crun version 1.8.1\\ncommit: f8a096be060b22ccd3d5f3ebe44108517fbf6c30\\nrundir: /run/user/1000/crun\\nspec: 1.0.0\\n+SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +YAJL\"\n },\n \"os\": \"linux\",\n \"remoteSocket\": {\n \"path\": \"unix:/run/user/1000/podman/podman.sock\",\n \"exists\": true\n },\n \"serviceIsRemote\": false,\n \"security\": {\n \"apparmorEnabled\": false,\n \"capabilities\": \"CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT\",\n \"rootless\": true,\n \"seccompEnabled\": true,\n \"seccompProfilePath\": \"/usr/share/containers/seccomp.json\",\n \"selinuxEnabled\": false\n },\n \"slirp4netns\": {\n \"executable\": \"/usr/bin/slirp4netns\",\n \"package\": \"slirp4netns_1.2.0-1_amd64\",\n \"version\": \"slirp4netns version 1.2.0\\ncommit: 656041d45cfca7a4176f6b7eed9e4fe6c11e8383\\nlibslirp: 4.7.0\\nSLIRP_CONFIG_VERSION_MAX: 4\\nlibseccomp: 2.5.4\"\n },\n \"swapFree\": 11401342,\n \"swapTotal\": 84237968,\n \"uptime\": \"14h 34m 45.00s (Approximately 0.58 days)\",\n \"linkmode\": \"dynamic\"\n },\n \"store\": {\n \"configFile\": \"/home/vagrant/.config/containers/storage.conf\",\n \"containerStore\": {\n \"number\": 6,\n \"paused\": 1,\n \"running\": 3,\n \"stopped\": 2\n },\n \"graphDriverName\": \"vfs\",\n \"graphOptions\": {},\n \"graphRoot\": \"/home/vagrant/.local/share/containers/storage\",\n \"graphRootAllocated\": 20956397568,\n \"graphRootUsed\": 18267197440,\n \"graphStatus\": {},\n \"imageCopyTmpDir\": \"/var/tmp\",\n \"imageStore\": {\n \"number\": 4\n },\n \"runRoot\": \"/run/user/1000/containers\",\n \"volumePath\": \"/home/vagrant/.local/share/containers/storage/volumes\"\n },\n \"registries\": {},\n \"plugins\": {\n \"volume\": [\n \"local\"\n ],\n \"network\": [\n \"bridge\",\n \"macvlan\"\n ],\n \"log\": [\n \"k8s-file\",\n \"none\",\n \"passthrough\",\n \"journald\"\n ],\n \"authorization\": null\n },\n \"version\": {\n \"APIVersion\": \"4.3.1\",\n \"Version\": \"4.3.1\",\n \"GoVersion\": \"go1.19.8\",\n \"GitCommit\": \"\",\n \"BuiltTime\": \"Thu Jan 1 00:00:00 1970\",\n \"Built\": 0,\n \"OsArch\": \"linux/amd64\",\n \"Os\": \"linux\"\n }\n}",
"latency": 0,
"statusCode": 200,
"label": "",
"headers": [],
"bodyType": "INLINE",
"filePath": "",
"databucketID": "",
"sendFileAsBody": false,
"rules": [],
"rulesOperator": "OR",
"disableTemplating": false,
"fallbackTo404": false,
"default": true,
"crudKey": "id",
"callbacks": []
}
],
"responseMode": null
},
{
"uuid": "9b757a53-25b9-4a95-a43b-8a6ba3be1344",
"type": "http",
"documentation": "",
"method": "get",
"endpoint": "v5.0.0/libpod/containers/json",
"responses": [
{
"uuid": "73f68e6e-2cbd-4770-9988-ac132f41ed27",
"body": "[\n {\n \"AutoRemove\": false,\n \"Command\": null,\n \"Created\": \"2025-01-28T10:46:54.159993093Z\",\n \"CreatedAt\": \"\",\n \"Exited\": false,\n \"ExitedAt\": 1738080827,\n \"ExitCode\": 0,\n \"Id\": \"89325e86fd779dda83c0189d01a0802351da38d05e4312932b11eef239c9935d\",\n \"Image\": \"localhost/podman-pause:4.3.1-0\",\n \"ImageID\": \"376c7556c90714e22370636dc094d03c860301ee72b4c4d5a1bc1ad91a015293\",\n \"IsInfra\": true,\n \"Labels\": {\n \"io.buildah.version\": \"1.28.2\"\n },\n \"Mounts\": [],\n \"Names\": [\n \"adc8d2ac5d64-infra\"\n ],\n \"Namespaces\": {},\n \"Networks\": [\n \"podman\"\n ],\n \"Pid\": 1326,\n \"Pod\": \"adc8d2ac5d64a38d9073f0c87f5137891a039c91ed8b7335c051528a0643046c\",\n \"PodName\": \"blog\",\n \"Ports\": [\n {\n \"host_ip\": \"\",\n \"container_port\": 80,\n \"host_port\": 8080,\n \"range\": 1,\n \"protocol\": \"tcp\"\n }\n ],\n \"Size\": null,\n \"StartedAt\": 1738241694,\n \"State\": \"running\",\n \"Status\": \"\"\n },\n {\n \"AutoRemove\": false,\n \"Command\": [\n \"apache2-foreground\"\n ],\n \"Created\": \"2025-01-28T10:47:41.119207776Z\",\n \"CreatedAt\": \"\",\n \"Exited\": false,\n \"ExitedAt\": 1738080828,\n \"ExitCode\": 0,\n \"Id\": \"ad7efe36dbceffde5dabeec4205501b599118bb427fc2305903ab42cf6fbe7a8\",\n \"Image\": \"docker.io/library/wordpress:latest\",\n \"ImageID\": \"c012b71a41fc3c0c778ba2d120c275cc75f5181852be1bff3402eb21d5a758de\",\n \"IsInfra\": false,\n \"Labels\": null,\n \"Mounts\": [\n \"/var/www/html\"\n ],\n \"Names\": [\n \"wordpress\"\n ],\n \"Namespaces\": {},\n \"Networks\": [],\n \"Pid\": 1331,\n \"Pod\": \"adc8d2ac5d64a38d9073f0c87f5137891a039c91ed8b7335c051528a0643046c\",\n \"PodName\": \"blog\",\n \"Ports\": [\n {\n \"host_ip\": \"\",\n \"container_port\": 80,\n \"host_port\": 8080,\n \"range\": 1,\n \"protocol\": \"tcp\"\n }\n ],\n \"Size\": null,\n \"StartedAt\": 1738241695,\n \"State\": \"running\",\n \"Status\": \"\"\n },\n {\n \"AutoRemove\": false,\n \"Command\": [\n \"httpd-foreground\"\n ],\n \"Created\": \"2025-01-28T10:48:15.222853918Z\",\n \"CreatedAt\": \"\",\n \"Exited\": false,\n \"ExitedAt\": 1738080827,\n \"ExitCode\": 0,\n \"Id\": \"480587ac39c4d852ec5cf8899d9a44788d32422f728679a7fa198723c23e3c35\",\n \"Image\": \"docker.io/library/httpd:latest\",\n \"ImageID\": \"f7d8bafbd9a9fc570c19628411a8441e8dc6697aa43c0c0cd863544f44fc4fb1\",\n \"IsInfra\": false,\n \"Labels\": null,\n \"Mounts\": [\n \"/usr/local/apache2/htdocs\"\n ],\n \"Names\": [\n \"httpd\"\n ],\n \"Namespaces\": {},\n \"Networks\": [],\n \"Pid\": 1443,\n \"Pod\": \"\",\n \"PodName\": \"\",\n \"Ports\": [\n {\n \"host_ip\": \"\",\n \"container_port\": 80,\n \"host_port\": 8081,\n \"range\": 1,\n \"protocol\": \"tcp\"\n }\n ],\n \"Size\": null,\n \"StartedAt\": 1738241724,\n \"State\": \"running\",\n \"Status\": \"\"\n }\n]",
"latency": 0,
"statusCode": 200,
"label": "",
"headers": [],
"bodyType": "INLINE",
"filePath": "",
"databucketID": "",
"sendFileAsBody": false,
"rules": [],
"rulesOperator": "OR",
"disableTemplating": false,
"fallbackTo404": false,
"default": true,
"crudKey": "id",
"callbacks": []
}
],
"responseMode": null
},
{
"uuid": "f8ac568a-c7e9-4116-9a2c-9de982ca9950",
"type": "http",
"documentation": "",
"method": "get",
"endpoint": "v5.0.0/libpod/pods/json",
"responses": [
{
"uuid": "08d5f43b-3ae6-43d5-9996-5d7356a6da67",
"body": "[\n {\n \"Cgroup\": \"user.slice\",\n \"Containers\": [\n {\n \"Id\": \"89325e86fd779dda83c0189d01a0802351da38d05e4312932b11eef239c9935d\",\n \"Names\": \"adc8d2ac5d64-infra\",\n \"Status\": \"running\"\n },\n {\n \"Id\": \"ad7efe36dbceffde5dabeec4205501b599118bb427fc2305903ab42cf6fbe7a8\",\n \"Names\": \"wordpress\",\n \"Status\": \"running\"\n },\n {\n \"Id\": \"fb20d214ce01fadfe16ef1a90781bfb494e4a1811e796c26f976782990352b28\",\n \"Names\": \"mysql\",\n \"Status\": \"exited\"\n }\n ],\n \"Created\": \"2025-01-28T10:46:54.146102881Z\",\n \"Id\": \"adc8d2ac5d64a38d9073f0c87f5137891a039c91ed8b7335c051528a0643046c\",\n \"InfraId\": \"89325e86fd779dda83c0189d01a0802351da38d05e4312932b11eef239c9935d\",\n \"Name\": \"blog\",\n \"Namespace\": \"\",\n \"Networks\": [\n \"podman\"\n ],\n \"Status\": \"Degraded\",\n \"Labels\": {}\n },\n {\n \"Cgroup\": \"user.slice\",\n \"Containers\": [\n {\n \"Id\": \"89325e86fd779dda83c0189d01a0802351da38d05e4312932b11eef239c9935d\",\n \"Names\": \"adc8d2ac5d64-infra2\",\n \"Status\": \"running\"\n },\n {\n \"Id\": \"ad7efe36dbceffde5dabeec4205501b599118bb427fc2305903ab42cf6fbe7a8\",\n \"Names\": \"wordpress2\",\n \"Status\": \"running\"\n },\n {\n \"Id\": \"fb20d214ce01fadfe16ef1a90781bfb494e4a1811e796c26f976782990352b28\",\n \"Names\": \"mysql2\",\n \"Status\": \"exited\"\n }\n ],\n \"Created\": \"2025-01-28T10:46:54.146102881Z\",\n \"Id\": \"adc8d2ac5d64a38d9073f0c87f5137891a039c91ed8b7335c051528a0643046d\",\n \"InfraId\": \"89325e86fd779dda83c0189d01a0802351da38d05e4312932b11eef239c9935d\",\n \"Name\": \"blog2\",\n \"Namespace\": \"\",\n \"Networks\": [\n \"podman\"\n ],\n \"Status\": \"Degraded\",\n \"Labels\": {}\n }\n]",
"latency": 0,
"statusCode": 200,
"label": "",
"headers": [],
"bodyType": "INLINE",
"filePath": "",
"databucketID": "",
"sendFileAsBody": false,
"rules": [],
"rulesOperator": "OR",
"disableTemplating": false,
"fallbackTo404": false,
"default": true,
"crudKey": "id",
"callbacks": []
}
],
"responseMode": null
},
{
"uuid": "29a8645f-5b09-44e3-a9af-130eb8674342",
"type": "http",
"documentation": "",
"method": "get",
"endpoint": "v5.0.0/libpod/pods/stats",
"responses": [
{
"uuid": "f6d96ff7-cc6e-468e-b284-cd3646d6bde9",
"body": "[\n {\n \"CPU\": \"0.00%\",\n \"MemUsage\": \"49.15kB / 2.052GB\",\n \"MemUsageBytes\": \"48KiB / 1.911GiB\",\n \"Mem\": \"0.00%\",\n \"NetIO\": \"4.718kB / 1.188kB\",\n \"BlockIO\": \"-- / --\",\n \"PIDS\": \"1\",\n \"Pod\": \"5de0484a9d3b\",\n \"CID\": \"465c966f5696\",\n \"Name\": \"5de0484a9d3b-infra\"\n },\n {\n \"CPU\": \"1.43%\",\n \"MemUsage\": \"450MB / 2.052GB\",\n \"MemUsageBytes\": \"429.1MiB / 1.911GiB\",\n \"Mem\": \"21.93%\",\n \"NetIO\": \"4.718kB / 1.188kB\",\n \"BlockIO\": \"0B / 123.9kB\",\n \"PIDS\": \"35\",\n \"Pod\": \"5de0484a9d3b\",\n \"CID\": \"b9434955e2b8\",\n \"Name\": \"mysql\"\n },\n {\n \"CPU\": \"0.03%\",\n \"MemUsage\": \"9.363MB / 2.052GB\",\n \"MemUsageBytes\": \"8.93MiB / 1.911GiB\",\n \"Mem\": \"0.46%\",\n \"NetIO\": \"4.718kB / 1.188kB\",\n \"BlockIO\": \"3.047MB / 82.37MB\",\n \"PIDS\": \"6\",\n \"Pod\": \"5de0484a9d3b\",\n \"CID\": \"bde2cd1fa1af\",\n \"Name\": \"wordpress\"\n }\n]",
"latency": 0,
"statusCode": 200,
"label": "",
"headers": [],
"bodyType": "INLINE",
"filePath": "",
"databucketID": "",
"sendFileAsBody": false,
"rules": [],
"rulesOperator": "OR",
"disableTemplating": false,
"fallbackTo404": false,
"default": true,
"crudKey": "id",
"callbacks": []
}
],
"responseMode": null
},
{
"uuid": "842a425b-7697-4c8d-8caf-1cd394c7fecc",
"type": "http",
"documentation": "",
"method": "get",
"endpoint": "v5.0.0/libpod/pods/:podName/json",
"responses": [
{
"uuid": "3b686944-9296-46ea-bfee-9ccdd90683f9",
"body": "[\n {\n \"Id\": \"5de0484a9d3bd4d2f0626292c6734fcf7de9059f6a6802298ed80c3c46b7207a\",\n \"Name\": \"{{urlParam 'podName'}}\",\n \"Created\": \"2025-02-04T09:21:22.076484809+01:00\",\n \"CreateCommand\": [\n \"podman\",\n \"pod\",\n \"create\",\n \"--name\",\n \"blog\",\n \"--infra\",\n \"--publish\",\n \"8080:80\",\n \"--network\",\n \"bridge\"\n ],\n \"ExitPolicy\": \"continue\",\n \"State\": {{#if (eq (urlParam 'podName') 'blog')}}\"Running\"{{else}}\"Degraded\"{{/if}},\n \"Hostname\": \"\",\n \"CreateCgroup\": true,\n \"CgroupParent\": \"user.slice\",\n \"CgroupPath\": \"user.slice/user-501.slice/user@501.service/user.slice/user-libpod_pod_5de0484a9d3bd4d2f0626292c6734fcf7de9059f6a6802298ed80c3c46b7207a.slice\",\n \"CreateInfra\": true,\n \"InfraContainerID\": \"465c966f56967d1e2cee42b8af6271375483875d1547e8a41238c5dbca9d91c4\",\n \"InfraConfig\": {\n \"PortBindings\": {\n \"80/tcp\": [\n {\n \"HostIp\": \"0.0.0.0\",\n \"HostPort\": \"8080\"\n }\n ]\n },\n \"HostNetwork\": false,\n \"StaticIP\": \"\",\n \"StaticMAC\": \"\",\n \"NoManageResolvConf\": false,\n \"DNSServer\": null,\n \"DNSSearch\": null,\n \"DNSOption\": null,\n \"NoManageHosts\": false,\n \"HostAdd\": null,\n \"Networks\": [\n \"podman\"\n ],\n \"NetworkOptions\": null,\n \"pid_ns\": \"private\",\n \"userns\": \"host\",\n \"uts_ns\": \"private\"\n },\n \"SharedNamespaces\": [\n \"uts\",\n \"ipc\",\n \"net\"\n ],\n \"NumContainers\": 3,\n \"Containers\": [\n {\n \"Id\": \"465c966f56967d1e2cee42b8af6271375483875d1547e8a41238c5dbca9d91c4\",\n \"Name\": \"5de0484a9d3b-infra\",\n \"State\": \"running\"\n },\n {\n \"Id\": \"b9434955e2b87c64e1d3b1ffb85768a9639486593765120c286cfebb2b04c830\",\n \"Name\": \"mysql\",\n \"State\": \"running\"\n },\n {\n \"Id\": \"bde2cd1fa1aff866cf5edd03d84677ed86792c9f1898861567ce4b1a1ca0a053\",\n \"Name\": \"wordpress\",\n \"State\": \"running\"\n },\n {\n \"Id\": \"bde2cd1fa1aff866cf5edd03d84677ed86792c9f1898861567ce4b1a1ca0a054\",\n \"Name\": \"run\",\n \"State\": \"running\"\n },\n {\n \"Id\": \"bde2cd1fa1aff866cf5edd03d84677ed86792c9f1898861567ce4b1a1ca0a053\",\n \"Name\": \"wordpress\",\n \"State\": \"running\"\n },\n {\n \"Id\": \"bde2cd1fa1aff866cf5edd03d84677ed86792c9f1898861567ce4b1a1ca0a063\",\n \"Name\": \"exit1\",\n \"State\": \"exited\"\n },\n {\n \"Id\": \"bde2cd1fa1aff866cf5edd03d84677ed86792c9f1898861567ce4b1a1ca0a064\",\n \"Name\": \"exit2\",\n \"State\": \"exited\"\n },\n {\n \"Id\": \"bde2cd1fa1aff866cf5edd03d84677ed86792c9f1898861567ce4b1a1ca0a073\",\n \"Name\": \"paused\",\n \"State\": \"paused\"\n }\n ],\n \"LockNumber\": 0\n }\n]",
"latency": 0,
"statusCode": 200,
"label": "",
"headers": [],
"bodyType": "INLINE",
"filePath": "",
"databucketID": "",
"sendFileAsBody": false,
"rules": [],
"rulesOperator": "OR",
"disableTemplating": false,
"fallbackTo404": false,
"default": true,
"crudKey": "id",
"callbacks": []
}
],
"responseMode": null
},
{
"uuid": "2f0c354c-a680-43a3-a970-e3621adba882",
"type": "http",
"documentation": "",
"method": "get",
"endpoint": "v5.0.0/libpod/containers/stats",
"responses": [
{
"uuid": "54839cdf-a8d4-4c21-b034-a9938ff776c7",
"body": "{\n \"Error\": null,\n \"Stats\": [\n {\n \"AvgCPU\": 0.10607938362643086,\n \"ContainerID\": \"76337a902ae6dbb440fb859574308d722046a9ced85d8bd012f203d28113b9b4\",\n \"Name\": \"wordpress\",\n \"PerCPU\": null,\n \"CPU\": 0.10607938362643086,\n \"CPUNano\": 859483000,\n \"CPUSystemNano\": 734368,\n \"SystemNano\": 1738829137318320000,\n \"MemUsage\": 11374592,\n \"MemLimit\": 2062614528,\n \"MemPerc\": 0.5514647475614018,\n \"NetInput\": 1006,\n \"NetOutput\": 2146,\n \"BlockInput\": 456812354,\n \"BlockOutput\": 987156423,\n \"PIDs\": 6,\n \"UpTime\": 859483000,\n \"Duration\": 859483000\n }\n ]\n}",
"latency": 0,
"statusCode": 200,
"label": "",
"headers": [],
"bodyType": "INLINE",
"filePath": "",
"databucketID": "",
"sendFileAsBody": false,
"rules": [],
"rulesOperator": "OR",
"disableTemplating": false,
"fallbackTo404": false,
"default": true,
"crudKey": "id",
"callbacks": []
}
],
"responseMode": null
}
],
"rootChildren": [
{
"type": "route",
"uuid": "f390a04c-57ee-49dc-a35a-62b296e75cdb"
},
{
"type": "route",
"uuid": "9b757a53-25b9-4a95-a43b-8a6ba3be1344"
},
{
"type": "route",
"uuid": "f8ac568a-c7e9-4116-9a2c-9de982ca9950"
},
{
"type": "route",
"uuid": "29a8645f-5b09-44e3-a9af-130eb8674342"
},
{
"type": "route",
"uuid": "842a425b-7697-4c8d-8caf-1cd394c7fecc"
},
{
"type": "route",
"uuid": "2f0c354c-a680-43a3-a970-e3621adba882"
}
],
"proxyMode": false,
"proxyHost": "",
"proxyRemovePrefix": false,
"tlsOptions": {
"enabled": false,
"type": "CERT",
"pfxPath": "",
"certPath": "",
"keyPath": "",
"caPath": "",
"passphrase": ""
},
"cors": true,
"headers": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "Access-Control-Allow-Origin",
"value": "*"
},
{
"key": "Access-Control-Allow-Methods",
"value": "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS"
},
{
"key": "Access-Control-Allow-Headers",
"value": "Content-Type, Origin, Accept, Authorization, Content-Length, X-Requested-With"
}
],
"proxyReqHeaders": [
{
"key": "",
"value": ""
}
],
"proxyResHeaders": [
{
"key": "",
"value": ""
}
],
"data": [],
"callbacks": []
}

View File

@ -0,0 +1,60 @@
*** Settings ***
Documentation Test the Podman pod-status mode
Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}podman.json
${cmd} ${CENTREON_PLUGINS}
... --plugin=apps::podman::restapi::plugin
... --custommode=api
... --mode=pod-status
... --hostname=${HOSTNAME}
... --port=${APIPORT}
... --proto=http
*** Test Cases ***
Pod status ${tc}
[Documentation] Check the pod status
[Tags] apps podman restapi
${command} Catenate
... ${cmd}
... --pod-name=blog
... ${extraoptions}
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc extraoptions expected_result --
... 1 ${EMPTY} OK: CPU: 1.46%, Memory: 459.41MB, Running containers: 5, Stopped containers: 2, Paused containers: 1, State: Running | 'podman.pod.cpu.usage.percent'=1.46%;;;0;100 'podman.pod.memory.usage.bytes'=481727346.688B;;;0; 'podman.pod.containers.running.count'=5;;;0; 'podman.pod.containers.stopped.count'=2;;;0; 'podman.pod.containers.paused.count'=1;;;0;
... 2 --warning-cpu-usage=1 WARNING: CPU: 1.46% | 'podman.pod.cpu.usage.percent'=1.46%;0:1;;0;100 'podman.pod.memory.usage.bytes'=481727346.688B;;;0; 'podman.pod.containers.running.count'=5;;;0; 'podman.pod.containers.stopped.count'=2;;;0; 'podman.pod.containers.paused.count'=1;;;0;
... 3 --critical-cpu-usage=1 CRITICAL: CPU: 1.46% | 'podman.pod.cpu.usage.percent'=1.46%;;0:1;0;100 'podman.pod.memory.usage.bytes'=481727346.688B;;;0; 'podman.pod.containers.running.count'=5;;;0; 'podman.pod.containers.stopped.count'=2;;;0; 'podman.pod.containers.paused.count'=1;;;0;
... 4 --warning-memory-usage=250000000 WARNING: Memory: 459.41MB | 'podman.pod.cpu.usage.percent'=1.46%;;;0;100 'podman.pod.memory.usage.bytes'=481727346.688B;0:250000000;;0; 'podman.pod.containers.running.count'=5;;;0; 'podman.pod.containers.stopped.count'=2;;;0; 'podman.pod.containers.paused.count'=1;;;0;
... 5 --critical-memory-usage=400000000 CRITICAL: Memory: 459.41MB | 'podman.pod.cpu.usage.percent'=1.46%;;;0;100 'podman.pod.memory.usage.bytes'=481727346.688B;;0:400000000;0; 'podman.pod.containers.running.count'=5;;;0; 'podman.pod.containers.stopped.count'=2;;;0; 'podman.pod.containers.paused.count'=1;;;0;
... 6 --warning-running-containers=3 WARNING: Running containers: 5 | 'podman.pod.cpu.usage.percent'=1.46%;;;0;100 'podman.pod.memory.usage.bytes'=481727346.688B;;;0; 'podman.pod.containers.running.count'=5;0:3;;0; 'podman.pod.containers.stopped.count'=2;;;0; 'podman.pod.containers.paused.count'=1;;;0;
... 7 --critical-running-containers=3 CRITICAL: Running containers: 5 | 'podman.pod.cpu.usage.percent'=1.46%;;;0;100 'podman.pod.memory.usage.bytes'=481727346.688B;;;0; 'podman.pod.containers.running.count'=5;;0:3;0; 'podman.pod.containers.stopped.count'=2;;;0; 'podman.pod.containers.paused.count'=1;;;0;
... 8 --warning-stopped-containers=0 WARNING: Stopped containers: 2 | 'podman.pod.cpu.usage.percent'=1.46%;;;0;100 'podman.pod.memory.usage.bytes'=481727346.688B;;;0; 'podman.pod.containers.running.count'=5;;;0; 'podman.pod.containers.stopped.count'=2;0:0;;0; 'podman.pod.containers.paused.count'=1;;;0;
... 9 --critical-stopped-containers=1 CRITICAL: Stopped containers: 2 | 'podman.pod.cpu.usage.percent'=1.46%;;;0;100 'podman.pod.memory.usage.bytes'=481727346.688B;;;0; 'podman.pod.containers.running.count'=5;;;0; 'podman.pod.containers.stopped.count'=2;;0:1;0; 'podman.pod.containers.paused.count'=1;;;0;
... 10 --warning-paused-containers=0 WARNING: Paused containers: 1 | 'podman.pod.cpu.usage.percent'=1.46%;;;0;100 'podman.pod.memory.usage.bytes'=481727346.688B;;;0; 'podman.pod.containers.running.count'=5;;;0; 'podman.pod.containers.stopped.count'=2;;;0; 'podman.pod.containers.paused.count'=1;0:0;;0;
... 11 --critical-paused-containers=0 CRITICAL: Paused containers: 1 | 'podman.pod.cpu.usage.percent'=1.46%;;;0;100 'podman.pod.memory.usage.bytes'=481727346.688B;;;0; 'podman.pod.containers.running.count'=5;;;0; 'podman.pod.containers.stopped.count'=2;;;0; 'podman.pod.containers.paused.count'=1;;0:0;0;
Pod status ${tc}
[Documentation] Check the pod status
[Tags] apps podman restapi
${command} Catenate
... ${cmd}
... --pod-name=degreded
... ${extraoptions}
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc extraoptions expected_result --
... 12 --warning-state='\\\%{state} =~ /Degraded/' --critical-state='\\\%{state} =~ /Exited/' WARNING: State: Degraded | 'podman.pod.cpu.usage.percent'=1.46%;;;0;100 'podman.pod.memory.usage.bytes'=481727346.688B;;;0; 'podman.pod.containers.running.count'=5;;;0; 'podman.pod.containers.stopped.count'=2;;;0; 'podman.pod.containers.paused.count'=1;;;0;
... 13 --warning-state='\\\%{state} =~ /Exited/' --critical-state='\\\%{state} =~ /Degraded/' CRITICAL: State: Degraded | 'podman.pod.cpu.usage.percent'=1.46%;;;0;100 'podman.pod.memory.usage.bytes'=481727346.688B;;;0; 'podman.pod.containers.running.count'=5;;;0; 'podman.pod.containers.stopped.count'=2;;;0; 'podman.pod.containers.paused.count'=1;;;0;

View File

@ -0,0 +1,46 @@
*** Settings ***
Documentation Test the Podman system-status mode
Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}podman.json
${cmd} ${CENTREON_PLUGINS}
... --plugin=apps::podman::restapi::plugin
... --custommode=api
... --mode=system-status
... --hostname=${HOSTNAME}
... --port=${APIPORT}
... --proto=http
*** Test Cases ***
System status ${tc}
[Documentation] Check the system status
[Tags] apps podman restapi
${command} Catenate
... ${cmd}
... ${extraoptions}
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc extraoptions expected_result --
... 1 ${EMPTY} OK: CPU: 1.19%, Memory: 1.84GB, Swap: 69.46MB, Running containers: 3, Stopped containers: 2, Uptime: 52440 s | 'podman.system.cpu.usage.percent'=1.19%;;;0;100 'podman.system.memory.usage.bytes'=1980252160B;;;0; 'podman.system.swap.usage.bytes'=72836626B;;;0; 'podman.system.containers.running.count'=3;;;0;6 'podman.system.containers.stopped.count'=2;;;0;6 'podman.system.uptime.seconds'=52440s;;;0;
... 2 --warning-cpu-usage=0.5 WARNING: CPU: 1.19% | 'podman.system.cpu.usage.percent'=1.19%;0:0.5;;0;100 'podman.system.memory.usage.bytes'=1980252160B;;;0; 'podman.system.swap.usage.bytes'=72836626B;;;0; 'podman.system.containers.running.count'=3;;;0;6 'podman.system.containers.stopped.count'=2;;;0;6 'podman.system.uptime.seconds'=52440s;;;0;
... 3 --critical-cpu-usage=1 CRITICAL: CPU: 1.19% | 'podman.system.cpu.usage.percent'=1.19%;;0:1;0;100 'podman.system.memory.usage.bytes'=1980252160B;;;0; 'podman.system.swap.usage.bytes'=72836626B;;;0; 'podman.system.containers.running.count'=3;;;0;6 'podman.system.containers.stopped.count'=2;;;0;6 'podman.system.uptime.seconds'=52440s;;;0;
... 4 --warning-memory-usage=1000000000 WARNING: Memory: 1.84GB | 'podman.system.cpu.usage.percent'=1.19%;;;0;100 'podman.system.memory.usage.bytes'=1980252160B;0:1000000000;;0; 'podman.system.swap.usage.bytes'=72836626B;;;0; 'podman.system.containers.running.count'=3;;;0;6 'podman.system.containers.stopped.count'=2;;;0;6 'podman.system.uptime.seconds'=52440s;;;0;
... 5 --critical-memory-usage=1500000000 CRITICAL: Memory: 1.84GB | 'podman.system.cpu.usage.percent'=1.19%;;;0;100 'podman.system.memory.usage.bytes'=1980252160B;;0:1500000000;0; 'podman.system.swap.usage.bytes'=72836626B;;;0; 'podman.system.containers.running.count'=3;;;0;6 'podman.system.containers.stopped.count'=2;;;0;6 'podman.system.uptime.seconds'=52440s;;;0;
... 6 --warning-swap-usage=25000000 WARNING: Swap: 69.46MB | 'podman.system.cpu.usage.percent'=1.19%;;;0;100 'podman.system.memory.usage.bytes'=1980252160B;;;0; 'podman.system.swap.usage.bytes'=72836626B;0:25000000;;0; 'podman.system.containers.running.count'=3;;;0;6 'podman.system.containers.stopped.count'=2;;;0;6 'podman.system.uptime.seconds'=52440s;;;0;
... 7 --critical-swap-usage=50000000 CRITICAL: Swap: 69.46MB | 'podman.system.cpu.usage.percent'=1.19%;;;0;100 'podman.system.memory.usage.bytes'=1980252160B;;;0; 'podman.system.swap.usage.bytes'=72836626B;;0:50000000;0; 'podman.system.containers.running.count'=3;;;0;6 'podman.system.containers.stopped.count'=2;;;0;6 'podman.system.uptime.seconds'=52440s;;;0;
... 8 --warning-containers-running=@2:4 WARNING: Running containers: 3 | 'podman.system.cpu.usage.percent'=1.19%;;;0;100 'podman.system.memory.usage.bytes'=1980252160B;;;0; 'podman.system.swap.usage.bytes'=72836626B;;;0; 'podman.system.containers.running.count'=3;@2:4;;0;6 'podman.system.containers.stopped.count'=2;;;0;6 'podman.system.uptime.seconds'=52440s;;;0;
... 9 --critical-containers-running=@0:4 CRITICAL: Running containers: 3 | 'podman.system.cpu.usage.percent'=1.19%;;;0;100 'podman.system.memory.usage.bytes'=1980252160B;;;0; 'podman.system.swap.usage.bytes'=72836626B;;;0; 'podman.system.containers.running.count'=3;;@0:4;0;6 'podman.system.containers.stopped.count'=2;;;0;6 'podman.system.uptime.seconds'=52440s;;;0;
... 10 --warning-containers-stopped=@1:2 WARNING: Stopped containers: 2 | 'podman.system.cpu.usage.percent'=1.19%;;;0;100 'podman.system.memory.usage.bytes'=1980252160B;;;0; 'podman.system.swap.usage.bytes'=72836626B;;;0; 'podman.system.containers.running.count'=3;;;0;6 'podman.system.containers.stopped.count'=2;@1:2;;0;6 'podman.system.uptime.seconds'=52440s;;;0;
... 11 --critical-containers-stopped=@2:6 CRITICAL: Stopped containers: 2 | 'podman.system.cpu.usage.percent'=1.19%;;;0;100 'podman.system.memory.usage.bytes'=1980252160B;;;0; 'podman.system.swap.usage.bytes'=72836626B;;;0; 'podman.system.containers.running.count'=3;;;0;6 'podman.system.containers.stopped.count'=2;;@2:6;0;6 'podman.system.uptime.seconds'=52440s;;;0;
... 12 --warning-uptime=@:60000 WARNING: Uptime: 52440 s | 'podman.system.cpu.usage.percent'=1.19%;;;0;100 'podman.system.memory.usage.bytes'=1980252160B;;;0; 'podman.system.swap.usage.bytes'=72836626B;;;0; 'podman.system.containers.running.count'=3;;;0;6 'podman.system.containers.stopped.count'=2;;;0;6 'podman.system.uptime.seconds'=52440s;@0:60000;;0;
... 13 --critical-uptime=@:120000 CRITICAL: Uptime: 52440 s | 'podman.system.cpu.usage.percent'=1.19%;;;0;100 'podman.system.memory.usage.bytes'=1980252160B;;;0; 'podman.system.swap.usage.bytes'=72836626B;;;0; 'podman.system.containers.running.count'=3;;;0;6 'podman.system.containers.stopped.count'=2;;;0;6 'podman.system.uptime.seconds'=52440s;;@0:120000;0;

View File

@ -0,0 +1,32 @@
*** Settings ***
Documentation Check Cyberoam equipments in SNMP.
Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource
Test Timeout 120s
Test Setup Ctn Generic Suite Setup
*** Variables ***
${CMD} ${CENTREON_PLUGINS} --plugin=network::cyberoam::snmp::plugin
*** Test Cases ***
ha-status ${tc}
[Tags] network cyberoam
${command} Catenate
... ${CMD}
... --mode=ha-status
... --hostname=${HOSTNAME}
... --snmp-version=${SNMPVERSION}
... --snmp-port=${SNMPPORT}
... --snmp-community=${SNMPCOMMUNITY}
... --snmp-timeout=1
... ${extra_options}
Ctn Verify Command Output ${command} ${expected_result}
Examples: tc extra_options SNMPCOMMUNITY expected_result --
... 1 ${EMPTY} network/cyberoam/snmp/slim_sophos OK: HA is 'enabled' - Current HA State: 'primary' - Peer HA State: 'auxiliary' - HA Port: 'Anonymized 007' - HA IP: '192.168.42.167' - Peer IP: '192.168.42.23'
... 2 --warning-status='\\\%{hastate} ne "down"' network/cyberoam/snmp/slim_sophos WARNING: HA is 'enabled' - Current HA State: 'primary' - Peer HA State: 'auxiliary' - HA Port: 'Anonymized 007' - HA IP: '192.168.42.167' - Peer IP: '192.168.42.23'
... 3 --critical-status='\\\%{hastatus} ne "down"' network/cyberoam/snmp/slim_sophos CRITICAL: HA is 'enabled' - Current HA State: 'primary' - Peer HA State: 'auxiliary' - HA Port: 'Anonymized 007' - HA IP: '192.168.42.167' - Peer IP: '192.168.42.23'
... 4 --no-ha-status='UNKNOWN' network/cyberoam/snmp/slim_sophos_no_ha UNKNOWN: Looks like HA is not enabled, or not applicable ..

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,34 @@
*** Settings ***
Documentation Check current HA-State. HA-States: notapplicable, auxiliary, standAlone,primary, faulty, ready.
Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource
Test Timeout 120s
Test Setup Ctn Generic Suite Setup
*** Variables ***
${CMD} ${CENTREON_PLUGINS} --plugin=network::cyberoam::snmp::plugin
*** Test Cases ***
ha-status ${tc}
[Tags] network cyberoam
${command} Catenate
... ${CMD}
... --mode=license
... --hostname=${HOSTNAME}
... --snmp-version=${SNMPVERSION}
... --snmp-port=${SNMPPORT}
... --snmp-community=network/cyberoam/snmp/slim_sophos
... --snmp-timeout=1
... ${extra_options}
Ctn Run Command And Check Result As Regexp ${command} ${expected_result}
Examples: tc extra_options expected_result --
... 1 ${EMPTY} OK: All licenses are ok \\\\| 'base_fw#license.expires.seconds'=\\\\d+s;;;0; 'net_protection#license.expires.seconds'=\\\\d+s;;;0; 'web_protection#license.expires.seconds'=\\\\d+s;;;0;
... 2 --unit=w OK: All licenses are ok \\\\| 'base_fw#license.expires.weeks'=\\\\d+w;;;0; 'net_protection#license.expires.weeks'=\\\\d+w;;;0; 'web_protection#license.expires.weeks'=\\\\d+w;;;0;
... 3 --unit=w --warning-expires=0 WARNING: License 'base_fw' expires in.* \\\\| 'base_fw#license.expires.weeks'=\\\\d+w;0:0;;0; 'net_protection#license.expires.weeks'=\\\\d+w;0:0;;0; 'web_protection#license.expires.weeks'=\\\\d+w;0:0;;0;
... 4 --unit=w --critical-expires=0 CRITICAL: License 'base_fw' expires in.* \\\\| 'base_fw#license.expires.weeks'=\\\\d+w;;0:0;0; 'net_protection#license.expires.weeks'=\\\\d+w;;0:0;0; 'web_protection#license.expires.weeks'=\\\\d+w;;0:0;0;
... 5 --unit=w --warning-expires=1000000: WARNING: License 'base_fw' expires in.* \\\\| 'base_fw#license.expires.weeks'=\\\\d+w;1000000:;;0; 'net_protection#license.expires.weeks'=\\\\d+w;1000000:;;0; 'web_protection#license.expires.weeks'=\\\\d+w;1000000:;;0;
... 6 --unit=w --critical-expires=1000000: CRITICAL: License 'base_fw' expires in.* \\\\| 'base_fw#license.expires.weeks'=\\\\d+w;;1000000:;0; 'net_protection#license.expires.weeks'=\\\\d+w;;1000000:;0; 'web_protection#license.expires.weeks'=\\\\d+w;;1000000:;0;

View File

@ -0,0 +1,40 @@
*** Settings ***
Documentation Check Cyberoam equipments in SNMP.
Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource
Test Timeout 120s
Test Setup Ctn Generic Suite Setup
*** Variables ***
${CMD} ${CENTREON_PLUGINS} --plugin=network::cyberoam::snmp::plugin
*** Test Cases ***
list-interfaces ${tc}
[Tags] network cyberoam
${command} Catenate
... ${CMD}
... --mode=list-interfaces
... --hostname=${HOSTNAME}
... --snmp-version=${SNMPVERSION}
... --snmp-port=${SNMPPORT}
... --snmp-community=network/cyberoam/snmp/slim_sophos
... --snmp-timeout=1
... ${extra_options}
Ctn Verify Command Output ${command} ${expected_result}
Examples: tc extra_options expected_result --
... 1 ${EMPTY} List interfaces: 'Anonymized 250' [speed = 10][status = up][id = 1][type = softwareLoopback] 'Anonymized 012' [speed = 1000][status = up][id = 10][type = ethernetCsmacd] 'Anonymized 118' [speed = 1000][status = up][id = 11][type = ethernetCsmacd] 'Anonymized 073' [speed = 1000][status = up][id = 12][type = ethernetCsmacd] 'Anonymized 071' [speed = ][status = down][id = 13][type = ethernetCsmacd] 'Anonymized 073' [speed = 1000][status = up][id = 14][type = ethernetCsmacd] 'Anonymized 232' [speed = ][status = down][id = 15][type = ethernetCsmacd] 'Anonymized 191' [speed = ][status = down][id = 16][type = ethernetCsmacd] 'Anonymized 242' [speed = 1000][status = up][id = 17][type = ethernetCsmacd] 'Anonymized 175' [speed = ][status = down][id = 18][type = ethernetCsmacd] 'Anonymized 128' [speed = ][status = down][id = 19][type = ethernetCsmacd] 'Anonymized 037' [speed = ][status = up][id = 2][type = ethernetCsmacd]
... 2 --interface=1 List interfaces: 'Anonymized 250' [speed = 10][status = up][id = 1][type = softwareLoopback]
... 3 --name='Anonymized 027' List interfaces: 'Anonymized 250' [speed = 10][status = up][id = 1][type = softwareLoopback] 'Anonymized 012' [speed = 1000][status = up][id = 10][type = ethernetCsmacd] 'Anonymized 118' [speed = 1000][status = up][id = 11][type = ethernetCsmacd] 'Anonymized 073' [speed = 1000][status = up][id = 12][type = ethernetCsmacd] 'Anonymized 071' [speed = ][status = down][id = 13][type = ethernetCsmacd] 'Anonymized 073' [speed = 1000][status = up][id = 14][type = ethernetCsmacd] 'Anonymized 232' [speed = ][status = down][id = 15][type = ethernetCsmacd] 'Anonymized 191' [speed = ][status = down][id = 16][type = ethernetCsmacd] 'Anonymized 242' [speed = 1000][status = up][id = 17][type = ethernetCsmacd] 'Anonymized 175' [speed = ][status = down][id = 18][type = ethernetCsmacd] 'Anonymized 128' [speed = ][status = down][id = 19][type = ethernetCsmacd] 'Anonymized 037' [speed = ][status = up][id = 2][type = ethernetCsmacd]
... 4 --speed=20 List interfaces: 'Anonymized 250' [speed = 20][status = up][id = 1][type = softwareLoopback] 'Anonymized 012' [speed = 20][status = up][id = 10][type = ethernetCsmacd] 'Anonymized 118' [speed = 20][status = up][id = 11][type = ethernetCsmacd] 'Anonymized 073' [speed = 20][status = up][id = 12][type = ethernetCsmacd] 'Anonymized 071' [speed = 20][status = down][id = 13][type = ethernetCsmacd] 'Anonymized 073' [speed = 20][status = up][id = 14][type = ethernetCsmacd] 'Anonymized 232' [speed = 20][status = down][id = 15][type = ethernetCsmacd] 'Anonymized 191' [speed = 20][status = down][id = 16][type = ethernetCsmacd] 'Anonymized 242' [speed = 20][status = up][id = 17][type = ethernetCsmacd] 'Anonymized 175' [speed = 20][status = down][id = 18][type = ethernetCsmacd] 'Anonymized 128' [speed = 20][status = down][id = 19][type = ethernetCsmacd] 'Anonymized 037' [speed = 20][status = up][id = 2][type = ethernetCsmacd]
... 5 --skip-speed0='' --name='Anonymized 232' List interfaces: 'Anonymized 250' [speed = 10][status = up][id = 1][type = softwareLoopback] 'Anonymized 012' [speed = 1000][status = up][id = 10][type = ethernetCsmacd] 'Anonymized 118' [speed = 1000][status = up][id = 11][type = ethernetCsmacd] 'Anonymized 073' [speed = 1000][status = up][id = 12][type = ethernetCsmacd] skipping interface 'Anonymized 071': interface speed is 0 and option --skip-speed0 is set 'Anonymized 073' [speed = 1000][status = up][id = 14][type = ethernetCsmacd] skipping interface 'Anonymized 232': interface speed is 0 and option --skip-speed0 is set skipping interface 'Anonymized 191': interface speed is 0 and option --skip-speed0 is set 'Anonymized 242' [speed = 1000][status = up][id = 17][type = ethernetCsmacd]
... 6 --filter-status='up' List interfaces: 'Anonymized 250' [speed = 10][status = up][id = 1][type = softwareLoopback] 'Anonymized 012' [speed = 1000][status = up][id = 10][type = ethernetCsmacd] 'Anonymized 118' [speed = 1000][status = up][id = 11][type = ethernetCsmacd] 'Anonymized 073' [speed = 1000][status = up][id = 12][type = ethernetCsmacd] skipping interface 'Anonymized 071': no matching filter status 'Anonymized 073' [speed = 1000][status = up][id = 14][type = ethernetCsmacd] skipping interface 'Anonymized 232': no matching filter status skipping interface 'Anonymized 191': no matching filter status 'Anonymized 242' [speed = 1000][status = up][id = 17][type = ethernetCsmacd] skipping interface 'Anonymized 175': no matching filter status skipping interface 'Anonymized 128': no matching filter status 'Anonymized 037' [speed = ][status = up][id = 2][type = ethernetCsmacd]
... 7 --use-adminstatus='down' List interfaces: 'Anonymized 250' [speed = 10][status = up][id = 1][type = softwareLoopback] 'Anonymized 012' [speed = 1000][status = up][id = 10][type = ethernetCsmacd] 'Anonymized 118' [speed = 1000][status = up][id = 11][type = ethernetCsmacd] 'Anonymized 073' [speed = 1000][status = up][id = 12][type = ethernetCsmacd] skipping interface 'Anonymized 071': adminstatus is not 'up' and option --use-adminstatus is set 'Anonymized 073' [speed = 1000][status = up][id = 14][type = ethernetCsmacd] 'Anonymized 232' [speed = ][status = down][id = 15][type = ethernetCsmacd] 'Anonymized 191' [speed = ][status = down][id = 16][type = ethernetCsmacd] 'Anonymized 242' [speed = 1000][status = up][id = 17][type = ethernetCsmacd] skipping interface 'Anonymized 175': adminstatus is not 'up' and option --use-adminstatus is set
... 8 --oid-filter='ifName' List interfaces: 'Anonymized 250' [speed = 10][status = up][id = 1][type = softwareLoopback] 'Anonymized 012' [speed = 1000][status = up][id = 10][type = ethernetCsmacd] 'Anonymized 118' [speed = 1000][status = up][id = 11][type = ethernetCsmacd] 'Anonymized 073' [speed = 1000][status = up][id = 12][type = ethernetCsmacd] 'Anonymized 071' [speed = ][status = down][id = 13][type = ethernetCsmacd] 'Anonymized 073' [speed = 1000][status = up][id = 14][type = ethernetCsmacd] 'Anonymized 232' [speed = ][status = down][id = 15][type = ethernetCsmacd] 'Anonymized 191' [speed = ][status = down][id = 16][type = ethernetCsmacd] 'Anonymized 242' [speed = 1000][status = up][id = 17][type = ethernetCsmacd] 'Anonymized 175' [speed = ][status = down][id = 18][type = ethernetCsmacd] 'Anonymized 128' [speed = ][status = down][id = 19][type = ethernetCsmacd] 'Anonymized 037' [speed = ][status = up][id = 2][type = ethernetCsmacd]
... 9 --oid-display='ifDesc' List interfaces: 'Anonymized 147' [speed = 10][status = up][id = 1][type = softwareLoopback] 'Anonymized 026' [speed = 1000][status = up][id = 10][type = ethernetCsmacd] 'Anonymized 232' [speed = 1000][status = up][id = 11][type = ethernetCsmacd] 'Anonymized 093' [speed = 1000][status = up][id = 12][type = ethernetCsmacd] 'Anonymized 058' [speed = ][status = down][id = 13][type = ethernetCsmacd] 'Anonymized 118' [speed = 1000][status = up][id = 14][type = ethernetCsmacd] 'Anonymized 158' [speed = ][status = down][id = 15][type = ethernetCsmacd] 'Anonymized 191' [speed = ][status = down][id = 16][type = ethernetCsmacd] 'Anonymized 160' [speed = 1000][status = up][id = 17][type = ethernetCsmacd] 'Anonymized 188' [speed = ][status = down][id = 18][type = ethernetCsmacd] 'Anonymized 034' [speed = ][status = down][id = 19][type = ethernetCsmacd] 'Anonymized 029' [speed = ][status = up][id = 2][type = ethernetCsmacd]
... 10 --display-transform-src='ens' --display-transform-dst='eth' List interfaces: 'Anonymized 250' [speed = 10][status = up][id = 1][type = softwareLoopback] 'Anonymized 012' [speed = 1000][status = up][id = 10][type = ethernetCsmacd] 'Anonymized 118' [speed = 1000][status = up][id = 11][type = ethernetCsmacd] 'Anonymized 073' [speed = 1000][status = up][id = 12][type = ethernetCsmacd] 'Anonymized 071' [speed = ][status = down][id = 13][type = ethernetCsmacd] 'Anonymized 073' [speed = 1000][status = up][id = 14][type = ethernetCsmacd] 'Anonymized 232' [speed = ][status = down][id = 15][type = ethernetCsmacd] 'Anonymized 191' [speed = ][status = down][id = 16][type = ethernetCsmacd] 'Anonymized 242' [speed = 1000][status = up][id = 17][type = ethernetCsmacd] 'Anonymized 175' [speed = ][status = down][id = 18][type = ethernetCsmacd] 'Anonymized 128' [speed = ][status = down][id = 19][type = ethernetCsmacd] 'Anonymized 037' [speed = ][status = up][id = 2][type = ethernetCsmacd]
... 11 --add-extra-oid='vlan,.1.3.6.1.2.1.31.19,\\\%{instance}\..*' List interfaces: 'Anonymized 250' [speed = 10][status = up][id = 1][type = softwareLoopback] 'Anonymized 012' [speed = 1000][status = up][id = 10][type = ethernetCsmacd] 'Anonymized 118' [speed = 1000][status = up][id = 11][type = ethernetCsmacd] 'Anonymized 073' [speed = 1000][status = up][id = 12][type = ethernetCsmacd] 'Anonymized 071' [speed = ][status = down][id = 13][type = ethernetCsmacd] 'Anonymized 073' [speed = 1000][status = up][id = 14][type = ethernetCsmacd] 'Anonymized 232' [speed = ][status = down][id = 15][type = ethernetCsmacd] 'Anonymized 191' [speed = ][status = down][id = 16][type = ethernetCsmacd] 'Anonymized 242' [speed = 1000][status = up][id = 17][type = ethernetCsmacd] 'Anonymized 175' [speed = ][status = down][id = 18][type = ethernetCsmacd] 'Anonymized 128' [speed = ][status = down][id = 19][type = ethernetCsmacd] 'Anonymized 037' [speed = ][status = up][id = 2][type = ethernetCsmacd]
... 12 --add-mac-address List interfaces: 'Anonymized 250' [speed = 10][status = up][id = 1][macaddress = ][type = softwareLoopback] 'Anonymized 012' [speed = 1000][status = up][id = 10][macaddress = 41:6e:6f:6e:79:6d:69:7a:65:64:20:30:38:34][type = ethernetCsmacd] 'Anonymized 118' [speed = 1000][status = up][id = 11][macaddress = 41:6e:6f:6e:79:6d:69:7a:65:64:20:31:38:34][type = ethernetCsmacd] 'Anonymized 073' [speed = 1000][status = up][id = 12][macaddress = 41:6e:6f:6e:79:6d:69:7a:65:64:20:30:37:32][type = ethernetCsmacd] 'Anonymized 071' [speed = ][status = down][id = 13][macaddress = 41:6e:6f:6e:79:6d:69:7a:65:64:20:31:31:39][type = ethernetCsmacd] 'Anonymized 073' [speed = 1000][status = up][id = 14][macaddress = 41:6e:6f:6e:79:6d:69:7a:65:64:20:30:31:30][type = ethernetCsmacd]

View File

@ -0,0 +1,32 @@
*** Settings ***
Documentation List VPN.
Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource
Test Timeout 120s
Test Setup Ctn Generic Suite Setup
*** Variables ***
${CMD} ${CENTREON_PLUGINS} --plugin=network::cyberoam::snmp::plugin
*** Test Cases ***
list-vpns ${tc}
[Tags] network cyberoam
${command} Catenate
... ${CMD}
... --mode=list-vpns
... --hostname=${HOSTNAME}
... --snmp-version=${SNMPVERSION}
... --snmp-port=${SNMPPORT}
... --snmp-community=network/cyberoam/snmp/slim_sophos
... --snmp-timeout=1
... ${extra_options}
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc extra_options expected_result --
... 1 ${EMPTY} List vpn [oid_path: 1] [name: Anonymized 093] [policy: Anonymized 208] [description: Anonymized 022] [connection_mode: Anonymized 245] [connection_type: site-to-site] [connection_status: active] [activated: active] [oid_path: 2] [name: Anonymized 252] [policy: Anonymized 055] [description: Anonymized 070] [connection_mode: Anonymized 123] [connection_type: site-to-site] [connection_status: active] [activated: active] [oid_path: 3] [name: Anonymized 029] [policy: Anonymized 151] [description: Anonymized 157] [connection_mode: Anonymized 055] [connection_type: site-to-site] [connection_status: inactive] [activated: active] [oid_path: 4] [name: Anonymized 132] [policy: Anonymized 089] [description: ] [connection_mode: Anonymized 185] [connection_type: site-to-site] [connection_status: active] [activated: active]
... 2 --filter-name='Anonymized 093' List vpn [oid_path: 1] [name: Anonymized 093] [policy: Anonymized 208] [description: Anonymized 022] [connection_mode: Anonymized 245] [connection_type: site-to-site] [connection_status: active] [activated: active]
... 3 --filter-connection-status='inactive' List vpn [oid_path: 3] [name: Anonymized 029] [policy: Anonymized 151] [description: Anonymized 157] [connection_mode: Anonymized 055] [connection_type: site-to-site] [connection_status: inactive] [activated: active]
... 4 --filter-vpn-activated='active' List vpn [oid_path: 1] [name: Anonymized 093] [policy: Anonymized 208] [description: Anonymized 022] [connection_mode: Anonymized 245] [connection_type: site-to-site] [connection_status: active] [activated: active] [oid_path: 2] [name: Anonymized 252] [policy: Anonymized 055] [description: Anonymized 070] [connection_mode: Anonymized 123] [connection_type: site-to-site] [connection_status: active] [activated: active] [oid_path: 3] [name: Anonymized 029] [policy: Anonymized 151] [description: Anonymized 157] [connection_mode: Anonymized 055] [connection_type: site-to-site] [connection_status: inactive] [activated: active] [oid_path: 4] [name: Anonymized 132] [policy: Anonymized 089] [description: ] [connection_mode: Anonymized 185] [connection_type: site-to-site] [connection_status: active] [activated: active]

View File

@ -0,0 +1,34 @@
*** Settings ***
Documentation Check memory usages.
Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource
Test Timeout 120s
Test Setup Ctn Generic Suite Setup
*** Variables ***
${CMD} ${CENTREON_PLUGINS} --plugin=network::cyberoam::snmp::plugin
*** Test Cases ***
memory ${tc}
[Tags] network cyberoam
${command} Catenate
... ${CMD}
... --mode=memory
... --hostname=${HOSTNAME}
... --snmp-version=${SNMPVERSION}
... --snmp-port=${SNMPPORT}
... --snmp-community=network/cyberoam/snmp/slim_sophos
... --snmp-timeout=1
... ${extra_options}
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc extra_options expected_result --
... 1 ${EMPTY} OK: Physical memory Total: 7.61 GB Used: 4.41 GB (58.00%) Free: 3.20 GB (42.00%) - Swap memory Total: 7.73 GB Used: 791.10 MB (10.00%) Free: 6.95 GB (90.00%) | 'physical_used'=4738284257.28B;;;0;8169455616 'swap_used'=829528473.6B;;;0;8295284736
... 2 --filter-counters='^physical-usage$' OK: Physical memory Total: 7.61 GB Used: 4.41 GB (58.00%) Free: 3.20 GB (42.00%) | 'physical_used'=4738284257.28B;;;0;8169455616
... 3 --warning-physical-usage=40 --critical-physical-usage=60 WARNING: Physical memory Total: 7.61 GB Used: 4.41 GB (58.00%) Free: 3.20 GB (42.00%) | 'physical_used'=4738284257.28B;0:3267782246;0:4901673369;0;8169455616 'swap_used'=829528473.6B;;;0;8295284736
... 4 --warning-swap-usage=100 --critical-swap-usage=0 CRITICAL: Swap memory Total: 7.73 GB Used: 791.10 MB (10.00%) Free: 6.95 GB (90.00%) | 'physical_used'=4738284257.28B;;;0;8169455616 'swap_used'=829528473.6B;0:8295284736;0:0;0;8295284736
... 5 --warning-physical-usage=60 --critical-physical-usage=40 CRITICAL: Physical memory Total: 7.61 GB Used: 4.41 GB (58.00%) Free: 3.20 GB (42.00%) | 'physical_used'=4738284257.28B;0:4901673369;0:3267782246;0;8169455616 'swap_used'=829528473.6B;;;0;8295284736
... 6 --warning-swap-usage=0 --critical-swap-usage=100 WARNING: Swap memory Total: 7.73 GB Used: 791.10 MB (10.00%) Free: 6.95 GB (90.00%) | 'physical_used'=4738284257.28B;;;0;8169455616 'swap_used'=829528473.6B;0:0;0:8295284736;0;8295284736

View File

@ -0,0 +1,39 @@
*** Settings ***
Documentation Check request statistics.
Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource
Test Timeout 120s
Test Setup Ctn Generic Suite Setup
*** Variables ***
${CMD} ${CENTREON_PLUGINS} --plugin=network::cyberoam::snmp::plugin
*** Test Cases ***
requests ${tc}
[Tags] network cyberoam
${command} Catenate
... ${CMD}
... --mode=requests
... --hostname=${HOSTNAME}
... --snmp-version=${SNMPVERSION}
... --snmp-port=${SNMPPORT}
... --snmp-community=network/cyberoam/snmp/slim_sophos
... --snmp-timeout=1
... ${extra_options}
# first run to build cache
Run ${command}
# second run to control the output
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc extra_options expected_result --
... 1 --filter-counters='' OK: Requests live users: 38, http hits: 0, ftp hits: 0, pop3 hits: 0, imap hits: 0, smtp hits: 0 | 'live_users'=38;;;0; 'http_hits'=0;;;0; 'ftp_hits'=0;;;0; 'pop3_hits'=0;;;0; 'imap_hits'=0;;;0; 'smtp_hits'=0;;;0;
... 2 --filter-counters='http' OK: Requests http hits: 0 | 'http_hits'=0;;;0;
... 3 --warning-live-users=0 --critical-live-users=0 CRITICAL: Requests live users: 38 | 'live_users'=38;0:0;0:0;0; 'http_hits'=0;;;0; 'ftp_hits'=0;;;0; 'pop3_hits'=0;;;0; 'imap_hits'=0;;;0; 'smtp_hits'=0;;;0;
... 4 --warning-http-hits=0 --critical-http-hits=10 OK: Requests live users: 38, http hits: 0, ftp hits: 0, pop3 hits: 0, imap hits: 0, smtp hits: 0 | 'live_users'=38;;;0; 'http_hits'=0;0:0;0:10;0; 'ftp_hits'=0;;;0; 'pop3_hits'=0;;;0; 'imap_hits'=0;;;0; 'smtp_hits'=0;;;0;
... 5 --warning-ftp-hits=5 --critical-ftp-hits=10 OK: Requests live users: 38, http hits: 0, ftp hits: 0, pop3 hits: 0, imap hits: 0, smtp hits: 0 | 'live_users'=38;;;0; 'http_hits'=0;;;0; 'ftp_hits'=0;0:5;0:10;0; 'pop3_hits'=0;;;0; 'imap_hits'=0;;;0; 'smtp_hits'=0;;;0;
... 6 --warning-smtp-hits=20 --critical-smtp-hits=10 OK: Requests live users: 38, http hits: 0, ftp hits: 0, pop3 hits: 0, imap hits: 0, smtp hits: 0 | 'live_users'=38;;;0; 'http_hits'=0;;;0; 'ftp_hits'=0;;;0; 'pop3_hits'=0;;;0; 'imap_hits'=0;;;0; 'smtp_hits'=0;0:20;0:10;0;
... 7 --warning-pop3-hits=80 --critical-pop3-hits=100 OK: Requests live users: 38, http hits: 0, ftp hits: 0, pop3 hits: 0, imap hits: 0, smtp hits: 0 | 'live_users'=38;;;0; 'http_hits'=0;;;0; 'ftp_hits'=0;;;0; 'pop3_hits'=0;0:80;0:100;0; 'imap_hits'=0;;;0; 'smtp_hits'=0;;;0;
... 8 --warning-imap-hits=50 --critical-imap-hits=50 OK: Requests live users: 38, http hits: 0, ftp hits: 0, pop3 hits: 0, imap hits: 0, smtp hits: 0 | 'live_users'=38;;;0; 'http_hits'=0;;;0; 'ftp_hits'=0;;;0; 'pop3_hits'=0;;;0; 'imap_hits'=0;0:50;0:50;0; 'smtp_hits'=0;;;0;

View File

@ -0,0 +1,32 @@
*** Settings ***
Documentation Check services.
Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource
Test Timeout 120s
Test Setup Ctn Generic Suite Setup
*** Variables ***
${CMD} ${CENTREON_PLUGINS} --plugin=network::cyberoam::snmp::plugin
*** Test Cases ***
services ${tc}
[Tags] network cyberoam
${command} Catenate
... ${CMD}
... --mode=services
... --hostname=${HOSTNAME}
... --snmp-version=${SNMPVERSION}
... --snmp-port=${SNMPPORT}
... --snmp-community=network/cyberoam/snmp/slim_sophos
... --snmp-timeout=1
... ${extra_options}
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc extra_options expected_result --
... 1 --component='service' OK: All 21 components are ok [21/21 services]. | 'hardware.service.count'=21;;;;
... 2 --filter='toto' OK: All 21 components are ok [21/21 services]. | 'hardware.service.count'=21;;;;
... 3 --no-component='UNKNOWN' OK: All 21 components are ok [21/21 services]. | 'hardware.service.count'=21;;;;
... 4 --threshold-overload='service,toto,OK,running' OK: All 21 components are ok [21/21 services]. | 'hardware.service.count'=21;;;;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,30 @@
*** Settings ***
Documentation Check storage usage.
Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource
Test Timeout 120s
Test Setup Ctn Generic Suite Setup
*** Variables ***
${CMD} ${CENTREON_PLUGINS} --plugin=network::cyberoam::snmp::plugin
*** Test Cases ***
storage ${tc}
[Tags] network cyberoam
${command} Catenate
... ${CMD}
... --mode=storage
... --hostname=${HOSTNAME}
... --snmp-version=${SNMPVERSION}
... --snmp-port=${SNMPPORT}
... --snmp-community=network/cyberoam/snmp/slim_sophos
... --snmp-timeout=1
... ${extra_options}
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc extra_options expected_result --
... 1 --warning-usage=0 WARNING: Storage Usage Total: 86.97 GB Used: 20.87 GB (24.00%) Free: 66.10 GB (76.00%) | 'used'=22411676221.44B;0:0;;0;93381984256
... 2 --critical-usage=0 CRITICAL: Storage Usage Total: 86.97 GB Used: 20.87 GB (24.00%) Free: 66.10 GB (76.00%) | 'used'=22411676221.44B;;0:0;0;93381984256

View File

@ -0,0 +1,43 @@
*** Settings ***
Documentation Check VPN status. VPN-Connection-Status: inactive, active,partiallyActive.
Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource
Test Timeout 120s
Test Setup Ctn Generic Suite Setup
*** Variables ***
${CMD} ${CENTREON_PLUGINS} --plugin=network::cyberoam::snmp::plugin
*** Test Cases ***
vpn-status ${tc}
[Tags] network cyberoam
${command} Catenate
... ${CMD}
... --mode=vpn-status
... --hostname=${HOSTNAME}
... --snmp-version=${SNMPVERSION}
... --snmp-port=${SNMPPORT}
... --snmp-community=network/cyberoam/snmp/slim_sophos
... --snmp-timeout=1
... ${extra_options}
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc extra_options expected_result --
... 1 --filter-counters='^total$|^total-normal$' OK: VPN total: 4 - All VPNs are ok | 'total'=4;;;0;
... 2 --filter-name='Anonymized 029' CRITICAL: VPN 'Anonymized 029' (Anonymized 157) status: inactive | 'total'=1;;;0; 'total_inactive'=1;;;0; 'total_active'=0;;;0; 'total_partially_active'=0;;;0;
... 3 --filter-name='Anonymized 132' OK: VPN total: 1, inactive: 0, active: 1, partially active: 0 - VPN 'Anonymized 132' status: active | 'total'=1;;;0; 'total_inactive'=0;;;0; 'total_active'=1;;;0; 'total_partially_active'=0;;;0;
... 4 --filter-vpn-activated='^inactive$' OK: VPN total : skipped (no value(s)), inactive: 0, active: 0, partially active: 0 | 'total_inactive'=0;;;0; 'total_active'=0;;;0; 'total_partially_active'=0;;;0;
... 5 --filter-vpn-activated='^active$' CRITICAL: VPN 'Anonymized 029' (Anonymized 157) status: inactive | 'total'=4;;;0; 'total_inactive'=1;;;0; 'total_active'=3;;;0; 'total_partially_active'=0;;;0;
... 6 --filter-connection-type='host-to-host' OK: VPN total : skipped (no value(s)), inactive: 0, active: 0, partially active: 0 | 'total_inactive'=0;;;0; 'total_active'=0;;;0; 'total_partially_active'=0;;;0;
... 7 --filter-connection-type='site-to-site' CRITICAL: VPN 'Anonymized 029' (Anonymized 157) status: inactive | 'total'=4;;;0; 'total_inactive'=1;;;0; 'total_active'=3;;;0; 'total_partially_active'=0;;;0;
... 8 --filter-connection-type='tunnel-interface' OK: VPN total : skipped (no value(s)), inactive: 0, active: 0, partially active: 0 | 'total_inactive'=0;;;0; 'total_active'=0;;;0; 'total_partially_active'=0;;;0;
... 9 --critical-status='' --warning-status='\\\%{connection_status} ne "active"' WARNING: VPN 'Anonymized 029' (Anonymized 157) status: inactive | 'total'=4;;;0; 'total_inactive'=1;;;0; 'total_active'=3;;;0; 'total_partially_active'=0;;;0;
... 10 --critical-status='' --warning-total=0 --critical-total=20 WARNING: VPN total: 4 | 'total'=4;0:0;0:20;0; 'total_inactive'=1;;;0; 'total_active'=3;;;0; 'total_partially_active'=0;;;0;
... 11 --critical-status='' --warning-total-inactive=10 --critical-total-inactive=0 CRITICAL: VPN inactive: 1 | 'total'=4;;;0; 'total_inactive'=1;0:10;0:0;0; 'total_active'=3;;;0; 'total_partially_active'=0;;;0;
... 12 --critical-status='' --warning-total-active=0 --critical-total-active=0 CRITICAL: VPN active: 3 | 'total'=4;;;0; 'total_inactive'=1;;;0; 'total_active'=3;0:0;0:0;0; 'total_partially_active'=0;;;0;
... 13 --critical-status='0' --warning-total-partially-active=1:1 WARNING: VPN partially active: 0 | 'total'=4;;;0; 'total_inactive'=1;;;0; 'total_active'=3;;;0; 'total_partially_active'=0;1:1;;0;
... 14 --critical-status='0' --critical-total-partially-active=1:1 CRITICAL: VPN partially active: 0 | 'total'=4;;;0; 'total_inactive'=1;;;0; 'total_active'=3;;;0; 'total_partially_active'=0;;1:1;0;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,35 @@
*** Settings ***
Documentation Check licenses.
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}License-api.json
${CMD} ${CENTREON_PLUGINS}
... --plugin=network::fortinet::fortigate::restapi::plugin
... --hostname=${HOSTNAME}
... --proto='http'
... --access-token=mokoon-token
... --port=${APIPORT}
*** Test Cases ***
licenses ${tc}
[Tags] network fortinet fortigate restapi
${command} Catenate
... ${CMD}
... --mode=licenses
... ${extra_options}
Ctn Verify Command Output ${command} ${expected_result}
Examples: tc extra_options expected_result --
... 1 --warning-status='\\\%{name} eq /web_filtering/i' CRITICAL: License 'ai_malware_detection' status: expired - License 'antispam' status: expired - License 'antivirus' status: expired - License 'blacklisted_certificates' status: expired - License 'botnet_domain' status: expired - License 'ips' status: expired - License 'malicious_urls' status: expired - License 'mobile_malware' status: expired - License 'web_filtering' status: expired | 'ai_malware_detection#license.expires.seconds'=0s;;;0; 'antispam#license.expires.seconds'=0s;;;0; 'antivirus#license.expires.seconds'=0s;;;0; 'appctrl#license.expires.seconds'=0s;;;0; 'blacklisted_certificates#license.expires.seconds'=0s;;;0; 'botnet_domain#license.expires.seconds'=0s;;;0; 'device_os_id#license.expires.seconds'=0s;;;0; 'forticare:support:enhanced#license.expires.seconds'=0s;;;0; 'forticare:support:hardware#license.expires.seconds'=0s;;;0; 'forticloud_sandbox#license.expires.seconds'=0s;;;0; 'fortiems_cloud#license.expires.seconds'=0s;;;0; 'ips#license.expires.seconds'=0s;;;0;
... 2 --critical-status='\\\%{status} =~ /unavailable/i' CRITICAL: License 'sms' status: unavailable | 'ai_malware_detection#license.expires.seconds'=0s;;;0; 'antispam#license.expires.seconds'=0s;;;0; 'antivirus#license.expires.seconds'=0s;;;0; 'appctrl#license.expires.seconds'=0s;;;0; 'blacklisted_certificates#license.expires.seconds'=0s;;;0; 'botnet_domain#license.expires.seconds'=0s;;;0; 'device_os_id#license.expires.seconds'=0s;;;0; 'forticare:support:enhanced#license.expires.seconds'=0s;;;0; 'forticare:support:hardware#license.expires.seconds'=0s;;;0; 'forticloud_sandbox#license.expires.seconds'=0s;;;0; 'fortiems_cloud#license.expires.seconds'=0s;;;0; 'ips#license.expires.seconds'=0s;;;0; 'malicious_urls#license.expires.seconds'=0s;;;0; 'mobile_malware#license.expires.seconds'=0s;;;0; 'web_filtering#license.expires.seconds'=0s;;;0;
... 3 --filter-name='sms' OK: License 'sms' status: unavailable
... 4 --unit='w' CRITICAL: License 'ai_malware_detection' status: expired - License 'antispam' status: expired - License 'antivirus' status: expired - License 'blacklisted_certificates' status: expired - License 'botnet_domain' status: expired - License 'ips' status: expired - License 'malicious_urls' status: expired - License 'mobile_malware' status: expired - License 'web_filtering' status: expired | 'ai_malware_detection#license.expires.weeks'=0w;;;0; 'antispam#license.expires.weeks'=0w;;;0; 'antivirus#license.expires.weeks'=0w;;;0; 'appctrl#license.expires.weeks'=0w;;;0; 'blacklisted_certificates#license.expires.weeks'=0w;;;0; 'botnet_domain#license.expires.weeks'=0w;;;0; 'device_os_id#license.expires.weeks'=0w;;;0; 'forticare:support:enhanced#license.expires.weeks'=0w;;;0; 'forticare:support:hardware#license.expires.weeks'=0w;;;0; 'forticloud_sandbox#license.expires.weeks'=0w;;;0; 'fortiems_cloud#license.expires.weeks'=0w;;;0; 'ips#license.expires.weeks'=0w;;;0; 'malicious_urls#license.expires.weeks'=0w;;;0; 'mobile_malware#license.expires.weeks'=0w;;;0; 'web_filtering#license.expires.weeks'=0w;;;0;
... 5 --critical-status='' --warning-expires=0 --critical-expires=20 OK: All licenses are ok | 'ai_malware_detection#license.expires.seconds'=0s;0:0;0:20;0; 'antispam#license.expires.seconds'=0s;0:0;0:20;0; 'antivirus#license.expires.seconds'=0s;0:0;0:20;0; 'appctrl#license.expires.seconds'=0s;0:0;0:20;0; 'blacklisted_certificates#license.expires.seconds'=0s;0:0;0:20;0; 'botnet_domain#license.expires.seconds'=0s;0:0;0:20;0; 'device_os_id#license.expires.seconds'=0s;0:0;0:20;0; 'forticare:support:enhanced#license.expires.seconds'=0s;0:0;0:20;0; 'forticare:support:hardware#license.expires.seconds'=0s;0:0;0:20;0; 'forticloud_sandbox#license.expires.seconds'=0s;0:0;0:20;0; 'fortiems_cloud#license.expires.seconds'=0s;0:0;0:20;0; 'ips#license.expires.seconds'=0s;0:0;0:20;0; 'malicious_urls#license.expires.seconds'=0s;0:0;0:20;0; 'mobile_malware#license.expires.seconds'=0s;0:0;0:20;0; 'web_filtering#license.expires.seconds'=0s;0:0;0:20;0;
... 6 --warning-status='' --warning-last-update=0 --critical-last-update=100 --filter-name='forticloud_sandbox' OK: License 'forticloud_sandbox' status: free_license, expires in 0 | 'forticloud_sandbox#license.expires.seconds'=0s;;;0;

View File

@ -0,0 +1,11 @@
.1.3.6.1.4.1.12356.101.4.9.2.1.2.7 = STRING: fgVWLHealthCheckLinkName
.1.3.6.1.4.1.12356.101.4.9.2.1.4.7 = INTEGER: 0
.1.3.6.1.4.1.12356.101.4.9.2.1.5.7 = STRING: 8.617
.1.3.6.1.4.1.12356.101.4.9.2.1.6.7 = STRING: 0.065
.1.3.6.1.4.1.12356.101.4.9.2.1.9.7 = STRING: 0.000
.1.3.6.1.4.1.12356.101.4.9.2.1.10.7 = STRING: root
.1.3.6.1.4.1.12356.101.4.9.2.1.11.7 = INTEGER: 27453
.1.3.6.1.4.1.12356.101.4.9.2.1.12.7 = INTEGER: 29552
.1.3.6.1.4.1.12356.101.4.9.2.1.13.7 = INTEGER: 57005
.1.3.6.1.4.1.12356.101.4.9.2.1.14.7 = STRING: wan1
.2.3.6.1.4.1.12356.101.4.9.2.1.2.7 = STRING: INTERNET

View File

@ -0,0 +1,36 @@
*** Settings ***
Documentation Check sd-wan links.
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Ctn Generic Suite Setup
Test Timeout 120s
*** Variables ***
${CMD} ${CENTREON_PLUGINS} --plugin=network::fortinet::fortigate::snmp::plugin
*** Test Cases ***
sdwan ${tc}
[Tags] network sdwan
${command} Catenate
... ${CMD}
... --mode=sdwan
... --hostname=${HOSTNAME}
... --snmp-version=${SNMPVERSION}
... --snmp-port=${SNMPPORT}
... --snmp-community=network/fortinet/fortigate/snmp/fortinet-fortigate
... --snmp-timeout=10
... --snmp-retries=3
... ${extra_options}
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc extra_options expected_result --
... 1 --filter-vdom='root' OK: sd-wan 'fgVWLHealthCheckLinkName' [vdom: root] [interface: wan1] state: up - traffic traffic-in : Buffer creation, traffic-out : Buffer creation, traffic-bi : Buffer creation - latency: 8.617ms - jitter: 0.065ms - packet loss: 0.000% | 'root~fgVWLHealthCheckLinkName~wan1#sdwan.latency.milliseconds'=8.62ms;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.jitter.milliseconds'=0.07ms;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.packetloss.percentage'=0.000%;;;0;100
... 2 --unknown-status='\\\%{vdom} eq "root"' UNKNOWN: sd-wan 'fgVWLHealthCheckLinkName' [vdom: root] [interface: wan1] state: up | 'root~fgVWLHealthCheckLinkName~wan1#sdwan.latency.milliseconds'=8.62ms;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.jitter.milliseconds'=0.07ms;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.packetloss.percentage'=0.000%;;;0;100
... 3 --warning-status='\\\%{state} eq "up"' WARNING: sd-wan 'fgVWLHealthCheckLinkName' [vdom: root] [interface: wan1] state: up | 'root~fgVWLHealthCheckLinkName~wan1#sdwan.traffic.in.bitspersecond'=0.00b/s;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.traffic.out.bitspersecond'=0.00b/s;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.traffic.bi.bitspersecond'=0.00b/s;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.latency.milliseconds'=8.62ms;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.jitter.milliseconds'=0.07ms;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.packetloss.percentage'=0.000%;;;0;100
... 4 --critical-status='\\\%{state} eq "up"' CRITICAL: sd-wan 'fgVWLHealthCheckLinkName' [vdom: root] [interface: wan1] state: up | 'root~fgVWLHealthCheckLinkName~wan1#sdwan.traffic.in.bitspersecond'=0.00b/s;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.traffic.out.bitspersecond'=0.00b/s;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.traffic.bi.bitspersecond'=0.00b/s;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.latency.milliseconds'=8.62ms;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.jitter.milliseconds'=0.07ms;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.packetloss.percentage'=0.000%;;;0;100
... 5 --critical-status='\\\%{vdom} eq "root"' --warning-traffic-in=0 --critical-traffic-in=8 CRITICAL: sd-wan 'fgVWLHealthCheckLinkName' [vdom: root] [interface: wan1] state: up | 'root~fgVWLHealthCheckLinkName~wan1#sdwan.traffic.in.bitspersecond'=0.00b/s;0:0;0:8;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.traffic.out.bitspersecond'=0.00b/s;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.traffic.bi.bitspersecond'=0.00b/s;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.latency.milliseconds'=8.62ms;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.jitter.milliseconds'=0.07ms;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.packetloss.percentage'=0.000%;;;0;100
... 6 ${EMPTY} OK: sd-wan 'fgVWLHealthCheckLinkName' [vdom: root] [interface: wan1] state: up - traffic in: 0.00 b/s, out: 0.00 b/s, bi: 0.00 b/s - latency: 8.617ms - jitter: 0.065ms - packet loss: 0.000% | 'root~fgVWLHealthCheckLinkName~wan1#sdwan.traffic.in.bitspersecond'=0.00b/s;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.traffic.out.bitspersecond'=0.00b/s;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.traffic.bi.bitspersecond'=0.00b/s;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.latency.milliseconds'=8.62ms;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.jitter.milliseconds'=0.07ms;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.packetloss.percentage'=0.000%;;;0;100
... 7 --warning-status='\\\%{vdom} eq "root"' --warning-latency=8 --critical-latency=16 WARNING: sd-wan 'fgVWLHealthCheckLinkName' [vdom: root] [interface: wan1] state: up - latency: 8.617ms | 'root~fgVWLHealthCheckLinkName~wan1#sdwan.traffic.in.bitspersecond'=0.00b/s;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.traffic.out.bitspersecond'=0.00b/s;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.traffic.bi.bitspersecond'=0.00b/s;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.latency.milliseconds'=8.62ms;0:8;0:16;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.jitter.milliseconds'=0.07ms;;;0; 'root~fgVWLHealthCheckLinkName~wan1#sdwan.packetloss.percentage'=0.000%;;;0;100

View File

@ -0,0 +1,27 @@
*** Settings ***
Documentation Network moxa SNMP plugin
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Ctn Generic Suite Setup
Test Timeout 120s
*** Variables ***
${CMD} ${CENTREON_PLUGINS}
... --plugin=network::moxa::switch::snmp::plugin
... --mode=interfaces
... --hostname=${HOSTNAME}
... --snmp-port=${SNMPPORT}
... --snmp-community=network/moxa/switch/snmp/interfaces
*** Test Cases ***
network interface ${tc}
[Tags] network moxa snmp
${command} Catenate
... ${CMD}
... ${arguments}
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc arguments expected_result --
... 1 --verbose --add-duplex-status OK: All interfaces are ok Interface 'lo' Status : up (admin: up) (duplex: fullDuplex) Interface 'eth0' Status : up (admin: up) (duplex: halfDuplex) Interface 'eth1' Status : up (admin: up) (duplex: unknown) Interface 'eth2' Status : up (admin: up) (duplex: fullDuplex) Interface 'eth3' Status : up (admin: up) (duplex: fullDuplex)

View File

@ -0,0 +1,103 @@
.1.3.6.1.2.1.1.1.0 = STRING: "Linux server-debian11 5.10.0-28-amd64 #1 SMP Debian 5.10.209-2 (2024-01-31) x86_64"
.1.3.6.1.2.1.1.3.0 = 8074
.1.3.6.1.2.1.2.2.1.2.1 = STRING: "lo"
.1.3.6.1.2.1.2.2.1.2.2 = STRING: "Intel Corporation 82540EM Gigabit Ethernet Controller"
.1.3.6.1.2.1.2.2.1.2.3 = STRING: "Intel Corporation 82540EM Gigabit Ethernet Controller"
.1.3.6.1.2.1.2.2.1.2.4 = STRING: "Intel Corporation 82540EM Gigabit Ethernet Controller"
.1.3.6.1.2.1.2.2.1.2.5 = STRING: "Intel Corporation 82540EM Gigabit Ethernet Controller"
.1.3.6.1.2.1.2.2.1.3.1 = INTEGER: 24
.1.3.6.1.2.1.2.2.1.3.2 = INTEGER: 6
.1.3.6.1.2.1.2.2.1.3.3 = INTEGER: 6
.1.3.6.1.2.1.2.2.1.3.4 = INTEGER: 6
.1.3.6.1.2.1.2.2.1.3.5 = INTEGER: 6
.1.3.6.1.2.1.2.2.1.5.1 = Gauge32: 10000000
.1.3.6.1.2.1.2.2.1.5.2 = Gauge32: 1000000000
.1.3.6.1.2.1.2.2.1.5.3 = Gauge32: 1000000000
.1.3.6.1.2.1.2.2.1.5.4 = Gauge32: 1000000000
.1.3.6.1.2.1.2.2.1.5.5 = Gauge32: 1000000000
.1.3.6.1.2.1.2.2.1.6.1 = ""
.1.3.6.1.2.1.2.2.1.6.2 = Hex-STRING: 08 00 27 8D C0 4D
.1.3.6.1.2.1.2.2.1.6.3 = Hex-STRING: 08 00 27 3C 26 92
.1.3.6.1.2.1.2.2.1.6.4 = Hex-STRING: 08 00 27 FE 8E E3
.1.3.6.1.2.1.2.2.1.6.5 = Hex-STRING: 08 00 27 A4 62 F7
.1.3.6.1.2.1.2.2.1.7.1 = INTEGER: 1
.1.3.6.1.2.1.2.2.1.7.2 = INTEGER: 1
.1.3.6.1.2.1.2.2.1.7.3 = INTEGER: 1
.1.3.6.1.2.1.2.2.1.7.4 = INTEGER: 1
.1.3.6.1.2.1.2.2.1.7.5 = INTEGER: 1
.1.3.6.1.2.1.2.2.1.8.1 = INTEGER: 1
.1.3.6.1.2.1.2.2.1.8.2 = INTEGER: 1
.1.3.6.1.2.1.2.2.1.8.3 = INTEGER: 1
.1.3.6.1.2.1.2.2.1.8.4 = INTEGER: 1
.1.3.6.1.2.1.2.2.1.8.5 = INTEGER: 1
.1.3.6.1.2.1.2.2.1.20.1 = Counter32: 0
.1.3.6.1.2.1.2.2.1.20.2 = Counter32: 0
.1.3.6.1.2.1.2.2.1.20.3 = Counter32: 0
.1.3.6.1.2.1.2.2.1.20.4 = Counter32: 0
.1.3.6.1.2.1.2.2.1.20.5 = Counter32: 0
.1.3.6.1.2.1.2.2.1.21.1 = Gauge32: 0
.1.3.6.1.2.1.2.2.1.21.2 = Gauge32: 0
.1.3.6.1.2.1.2.2.1.21.3 = Gauge32: 0
.1.3.6.1.2.1.2.2.1.21.4 = Gauge32: 0
.1.3.6.1.2.1.2.2.1.21.5 = Gauge32: 0
.1.3.6.1.2.1.2.2.1.22.1 = OID: .0.0
.1.3.6.1.2.1.2.2.1.22.2 = OID: .0.0
.1.3.6.1.2.1.2.2.1.22.3 = OID: .0.0
.1.3.6.1.2.1.2.2.1.22.4 = OID: .0.0
.1.3.6.1.2.1.2.2.1.22.5 = OID: .0.0
.1.3.6.1.2.1.25.1.1.0 = 48160
.1.3.6.1.2.1.31.1.1.1.1.1 = STRING: "lo"
.1.3.6.1.2.1.31.1.1.1.1.2 = STRING: "eth0"
.1.3.6.1.2.1.31.1.1.1.1.3 = STRING: "eth1"
.1.3.6.1.2.1.31.1.1.1.1.4 = STRING: "eth2"
.1.3.6.1.2.1.31.1.1.1.1.5 = STRING: "eth3"
.1.3.6.1.2.1.31.1.1.1.10.1 = Counter64: 1904
.1.3.6.1.2.1.31.1.1.1.10.2 = Counter64: 192208
.1.3.6.1.2.1.31.1.1.1.10.3 = Counter64: 647510
.1.3.6.1.2.1.31.1.1.1.10.4 = Counter64: 1592
.1.3.6.1.2.1.31.1.1.1.10.5 = Counter64: 1592
.1.3.6.1.2.1.31.1.1.1.11.1 = Counter64: 20
.1.3.6.1.2.1.31.1.1.1.11.2 = Counter64: 1339
.1.3.6.1.2.1.31.1.1.1.11.3 = Counter64: 5865
.1.3.6.1.2.1.31.1.1.1.11.4 = Counter64: 20
.1.3.6.1.2.1.31.1.1.1.11.5 = Counter64: 20
.1.3.6.1.2.1.31.1.1.1.12.1 = Counter64: 0
.1.3.6.1.2.1.31.1.1.1.12.2 = Counter64: 0
.1.3.6.1.2.1.31.1.1.1.12.3 = Counter64: 0
.1.3.6.1.2.1.31.1.1.1.12.4 = Counter64: 0
.1.3.6.1.2.1.31.1.1.1.12.5 = Counter64: 0
.1.3.6.1.2.1.31.1.1.1.13.1 = Counter64: 0
.1.3.6.1.2.1.31.1.1.1.13.2 = Counter64: 0
.1.3.6.1.2.1.31.1.1.1.13.3 = Counter64: 0
.1.3.6.1.2.1.31.1.1.1.13.4 = Counter64: 0
.1.3.6.1.2.1.31.1.1.1.13.5 = Counter64: 0
.1.3.6.1.2.1.31.1.1.1.15.1 = Gauge32: 10
.1.3.6.1.2.1.31.1.1.1.15.2 = Gauge32: 1000
.1.3.6.1.2.1.31.1.1.1.15.3 = Gauge32: 1000
.1.3.6.1.2.1.31.1.1.1.15.4 = Gauge32: 1000
.1.3.6.1.2.1.31.1.1.1.15.5 = Gauge32: 1000
.1.3.6.1.2.1.31.1.1.1.16.1 = INTEGER: 2
.1.3.6.1.2.1.31.1.1.1.16.2 = INTEGER: 2
.1.3.6.1.2.1.31.1.1.1.16.3 = INTEGER: 2
.1.3.6.1.2.1.31.1.1.1.16.4 = INTEGER: 2
.1.3.6.1.2.1.31.1.1.1.16.5 = INTEGER: 2
.1.3.6.1.2.1.31.1.1.1.17.1 = INTEGER: 2
.1.3.6.1.2.1.31.1.1.1.17.2 = INTEGER: 1
.1.3.6.1.2.1.31.1.1.1.17.3 = INTEGER: 1
.1.3.6.1.2.1.31.1.1.1.17.4 = INTEGER: 1
.1.3.6.1.2.1.31.1.1.1.17.5 = INTEGER: 1
.1.3.6.1.2.1.31.1.1.1.18.1 = ""
.1.3.6.1.2.1.31.1.1.1.18.2 = ""
.1.3.6.1.2.1.31.1.1.1.18.3 = ""
.1.3.6.1.2.1.31.1.1.1.18.4 = ""
.1.3.6.1.2.1.31.1.1.1.18.5 = ""
.1.3.6.1.2.1.31.1.1.1.19.1 = 0
.1.3.6.1.2.1.31.1.1.1.19.2 = 0
.1.3.6.1.2.1.31.1.1.1.19.3 = 0
.1.3.6.1.2.1.31.1.1.1.19.4 = 0
.1.3.6.1.2.1.31.1.1.1.19.5 = 0
.1.3.6.1.4.1.8691.7.6.1.10.3.1.3.1 = INTEGER: 3
.1.3.6.1.4.1.8691.7.6.1.10.3.1.3.2 = INTEGER: 2
.1.3.6.1.4.1.8691.7.6.1.10.3.1.3.3 = INTEGER: -1
.1.3.6.1.4.1.8691.7.6.1.10.3.1.3.4 = INTEGER: 1
.1.3.6.1.4.1.8691.7.6.1.10.3.1.3.5 = INTEGER: 3

View File

@ -51,6 +51,7 @@ cpu-utilization-1m
cpu-utilization-5m
cpu-utilization-5s
CX
Cyberoam
Datacore
datasource
DC4
@ -61,7 +62,6 @@ dev
df
--dfsr
dfsrevent
--diskpath
--display-transform-dst
--display-transform-src
dns-resolve-time
@ -85,9 +85,11 @@ FCCapacity
--force-oid
Fortigate
Fortinet
FQDN
FreeBSD
frsevent
--get-param
HAProxy
HashiCorp
hashicorpvault
HPE
@ -97,9 +99,9 @@ ifAlias
ifDesc
ifName
--ignore-orgs-api-disabled
IKS
IMEI
in-bcast
includeAllDisks
in-crc
in-fcserror
in-mcast
@ -172,6 +174,7 @@ NLCapacity
--noidle
-NoLogo
--nomachineaccount
notapplicable
--ntlmv2
NTLMv2
NTP
@ -190,10 +193,13 @@ out-fc-wait
out-mcast
out-ucast
overprovisioning
packetloss
partiallyActive
--patch-redhat
perfdata
physicaldrive
PKCS1
Podman
powershell
powershell.exe
PPID
@ -214,7 +220,7 @@ Sansymphony
SAS
scenarii
--scope-datacenter
SFDC
SFOS
sfp.temperature
--skip-ssl-check
SkyHigh
@ -226,6 +232,7 @@ space-usage-prct
--sql-errors-exit
SSDCapacity
SSH
standAlone
statefile
--statefile-concat-cwd
SureBackup
@ -256,14 +263,15 @@ userpass
--use-ucd
v1
v2
vdom
VDSL2
Veeam
VeloCloud
Vserver
VM
VMware
VPN
vSAN
Vserver
vSphere
--warning-authserver-clients-timeout
--warning-authserver-packets-access-accepts