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 merge-multiple: true
- name: Upload the Regrouped Artifact - name: Upload the Regrouped Artifact
uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # v4.0.0 uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with: with:
name: ${{ inputs.target_name }} name: ${{ inputs.target_name }}
path: | path: |

View File

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

View File

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

View File

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

View File

@ -10,10 +10,22 @@ baseurl=https://repo.goreleaser.com/yum/
enabled=1 enabled=1
gpgcheck=0' | tee /etc/yum.repos.d/goreleaser.repo 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 dnf -y install perl-App-cpanminus perl-JSON
cpanm App::FatPacker cpanm App::FatPacker
cpanm File::Copy::Recursive 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 dnf clean all
EOF EOF

View File

@ -10,10 +10,22 @@ baseurl=https://repo.goreleaser.com/yum/
enabled=1 enabled=1
gpgcheck=0' | tee /etc/yum.repos.d/goreleaser.repo 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 dnf -y install perl-App-cpanminus perl-JSON
cpanm App::FatPacker cpanm App::FatPacker
cpanm File::Copy::Recursive 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 dnf clean all
EOF EOF

View File

@ -55,6 +55,8 @@ apt-get install -y \
cpanm Module::Build::Tiny cpanm Module::Build::Tiny
cpanm Module::Install cpanm Module::Install
cpanm Crypt::OpenSSL::Guess
gem install fpm gem install fpm
echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | tee /etc/apt/sources.list.d/goreleaser.list 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 apt-get clean
EOF 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 \ libapp-fatpacker-perl \
libcurl4-openssl-dev \ libcurl4-openssl-dev \
libczmq-dev \ libczmq-dev \
libczmq-dev\
libfile-copy-recursive-perl \ libfile-copy-recursive-perl \
libjson-perl \ libjson-perl \
libmodule-build-tiny-perl \ libmodule-build-tiny-perl \
@ -58,7 +57,6 @@ cpanm Crypt::OpenSSL::Guess
gem install fpm gem install fpm
echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | tee /etc/apt/sources.list.d/goreleaser.list echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | tee /etc/apt/sources.list.d/goreleaser.list
apt-get update apt-get update
apt-get install -y nfpm=2.41.0 apt-get install -y nfpm=2.41.0
@ -66,3 +64,7 @@ apt-get install -y nfpm=2.41.0
apt-get clean apt-get clean
EOF 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 apt-get clean
EOF 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 }} stability: ${{ needs.get-environment.outputs.stability }}
- name: Save to cache - name: Save to cache
uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with: with:
path: ./*.${{ matrix.package_extension }} path: ./*.${{ matrix.package_extension }}
key: ${{ github.sha }}-${{ github.run_id }}-${{ matrix.package_extension }}-${{ matrix.distrib }} 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 }} stability: ${{ needs.get-environment.outputs.stability }}
- name: Upload apt/dnf packages as artifacts if asked - name: Upload apt/dnf packages as artifacts if asked
if: ${{ contains(github.event.pull_request.labels.*.name, 'upload-artifacts') }} 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: with:
name: vmware-connector-daemon-${{ matrix.distrib }} name: vmware-connector-daemon-${{ matrix.distrib }}
path: centreon-plugin* path: centreon-plugin*

View File

@ -84,9 +84,9 @@ jobs:
username: ${{ secrets.HARBOR_CENTREON_PUSH_USERNAME }} username: ${{ secrets.HARBOR_CENTREON_PUSH_USERNAME }}
password: ${{ secrets.HARBOR_CENTREON_PUSH_TOKEN }} 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: with:
file: .github/docker/packaging/Dockerfile.${{ matrix.dockerfile }} file: .github/docker/packaging/Dockerfile.${{ matrix.dockerfile }}
context: . context: .

View File

@ -69,9 +69,9 @@ jobs:
username: ${{ secrets.HARBOR_CENTREON_PUSH_USERNAME }} username: ${{ secrets.HARBOR_CENTREON_PUSH_USERNAME }}
password: ${{ secrets.HARBOR_CENTREON_PUSH_TOKEN }} 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: with:
file: .github/docker/testing/Dockerfile.testing-plugins-${{ matrix.dockerfile }} file: .github/docker/testing/Dockerfile.testing-plugins-${{ matrix.dockerfile }}
context: . context: .

View File

@ -69,9 +69,9 @@ jobs:
username: ${{ secrets.HARBOR_CENTREON_PUSH_USERNAME }} username: ${{ secrets.HARBOR_CENTREON_PUSH_USERNAME }}
password: ${{ secrets.HARBOR_CENTREON_PUSH_TOKEN }} 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: with:
file: .github/docker/unit-tests/Dockerfile.unit-tests-${{ matrix.dockerfile }} file: .github/docker/unit-tests/Dockerfile.unit-tests-${{ matrix.dockerfile }}
context: . context: .

View File

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

View File

@ -92,6 +92,7 @@ jobs:
- rpm_provides: "" - rpm_provides: ""
- version: "" - version: ""
- spec_file: "" - spec_file: ""
- no-auto-depends: false
- distrib: el8 - distrib: el8
package_extension: rpm package_extension: rpm
image: packaging-plugins-alma8 image: packaging-plugins-alma8
@ -112,6 +113,10 @@ jobs:
rpm_provides: "perl(FFI::Platypus::Buffer) perl(FFI::Platypus::Memory)" 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)" 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 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" - name: "Net::DHCP"
rpm_provides: "perl(Net::DHCP::Constants) perl(Net::DHCP::Packet)" rpm_provides: "perl(Net::DHCP::Constants) perl(Net::DHCP::Packet)"
- name: "Net::SMTPS" - name: "Net::SMTPS"
@ -131,11 +136,6 @@ jobs:
- name: "ZMQ::LibZMQ4" - name: "ZMQ::LibZMQ4"
version: "0.01" version: "0.01"
rpm_dependencies: "zeromq" 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 }} name: package ${{ matrix.distrib }} ${{ matrix.name }}
container: container:
@ -149,35 +149,25 @@ jobs:
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- if: ${{ contains(matrix.build_distribs, matrix.distrib) }} - if: ${{ contains(matrix.build_distribs, matrix.distrib) }}
name: Check if package already exists
id: check-package-existence
run: | run: |
yum install -y yum-utils epel-release git package_info=$(dnf provides 'perl(${{ matrix.name }})' 2>&1 | tr '[:upper:]' '[:lower:]' || true)
yum config-manager --set-enabled crb || true # alma 9 do_not_build="false"
yum config-manager --set-enabled powertools || true # alma 8 if [[ ! $package_info =~ "no matches found" ]]; then
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 package_version=$(echo $package_info | grep -oP 'perl\(${{ matrix.name }}\) = \K[0-9]+\.[0-9]+')
if [[ -z "${{ matrix.version }}" || "$package_version" == "${{ matrix.version }}" ]]; then
dnf module reset -y ruby echo "::warning::Package ${{ matrix.name }} already exists in the official ${{ matrix.distrib }} repository with the same version."
dnf module enable -y ruby:3.1 do_not_build="true"
dnf install -y ruby ruby-devel 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 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) && matrix.spec_file == '' }}
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 == '' }}
run: | run: |
if [ -z "${{ matrix.version }}" ]; then if [ -z "${{ matrix.version }}" ]; then
PACKAGE_VERSION="" PACKAGE_VERSION=""
@ -205,15 +195,20 @@ jobs:
done done
fi fi
cpanm Module::Build::Tiny
cpanm Module::Install
export SYBASE="/usr" 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 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: | run: |
mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS} mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
@ -222,7 +217,7 @@ jobs:
cp -r ~/rpmbuild/RPMS/noarch/*.rpm . cp -r ~/rpmbuild/RPMS/noarch/*.rpm .
shell: bash 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 name: Replace '::' with - in the feature path
id: package-name id: package-name
run: | run: |
@ -232,8 +227,8 @@ jobs:
echo "name_with_dash=$name_with_dash" >> $GITHUB_OUTPUT echo "name_with_dash=$name_with_dash" >> $GITHUB_OUTPUT
shell: bash 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) }}
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with: with:
name: packages-${{ matrix.package_extension }}-${{ matrix.distrib }}-${{ steps.package-name.outputs.name_with_dash }} name: packages-${{ matrix.package_extension }}-${{ matrix.distrib }}-${{ steps.package-name.outputs.name_with_dash }}
path: ./*.${{ matrix.package_extension }} path: ./*.${{ matrix.package_extension }}
@ -251,7 +246,7 @@ jobs:
steps: steps:
- name: Merge Artifacts - name: Merge Artifacts
uses: actions/upload-artifact/merge@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 uses: actions/upload-artifact/merge@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with: with:
name: packages-rpm-${{ matrix.distrib }} name: packages-rpm-${{ matrix.distrib }}
pattern: packages-rpm-${{ matrix.distrib }}-* pattern: packages-rpm-${{ matrix.distrib }}-*
@ -299,7 +294,7 @@ jobs:
- run: rpmsign --addsign ./*.rpm - run: rpmsign --addsign ./*.rpm
shell: bash shell: bash
- uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 - uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with: with:
path: ./*.rpm path: ./*.rpm
key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
@ -318,7 +313,6 @@ jobs:
name: name:
[ [
"ARGV::Struct", "ARGV::Struct",
"Authen::SCRAM::Client",
"Config::AWS", "Config::AWS",
"Convert::EBCDIC", "Convert::EBCDIC",
"Crypt::Blowfish_PP", "Crypt::Blowfish_PP",
@ -338,42 +332,51 @@ jobs:
"Net::FTPSSL", "Net::FTPSSL",
"Net::HTTPTunnel", "Net::HTTPTunnel",
"Net::MQTT::Simple", "Net::MQTT::Simple",
"Net::SMTP_auth",
"Paws", "Paws",
"Statistics::Regression", "Statistics::Regression",
"WWW::Selenium", "XS::Loader",
"ZMQ::Constants", "ZMQ::Constants",
"ZMQ::LibZMQ4" "ZMQ::LibZMQ4"
] ]
include: include:
- runner_name: ubuntu-24.04 - runner_name: ubuntu-24.04
- arch: amd64 - arch: amd64
- build_distribs: "bullseye,bookworm,jammy" - build_names: "bullseye-amd64,bookworm,jammy"
- deb_dependencies: "" - deb_dependencies: ""
- rpm_provides: "" - rpm_provides: ""
- version: "" - version: ""
- use_dh_make_perl: "true" - use_dh_make_perl: "true"
- spec_file: "" - build_name: bullseye-amd64
- distrib: bullseye distrib: bullseye
package_extension: deb package_extension: deb
image: packaging-plugins-bullseye image: packaging-plugins-bullseye
- distrib: bookworm - build_name: bookworm
distrib: bookworm
package_extension: deb package_extension: deb
image: packaging-plugins-bookworm image: packaging-plugins-bookworm
- distrib: jammy - build_name: jammy
distrib: jammy
package_extension: deb package_extension: deb
image: packaging-plugins-jammy image: packaging-plugins-jammy
- distrib: bullseye - build_name: bullseye-arm64
distrib: bullseye
package_extension: deb package_extension: deb
image: packaging-plugins-bullseye-arm64 image: packaging-plugins-bullseye-arm64
arch: arm64 arch: arm64
runner_name: ["self-hosted", "collect-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" - name: "Device::Modbus::RTU::Client"
build_distribs: "bookworm" build_names: "bookworm"
- name: "Device::Modbus::TCP::Client" - name: "Device::Modbus::TCP::Client"
build_distribs: "bookworm" build_names: "bookworm"
- name: "Digest::SHA1"
build_names: "jammy"
- name: "Net::Amazon::Signature::V4" - name: "Net::Amazon::Signature::V4"
build_distribs: ["bullseye", "jammy"] build_names: ["bullseye-amd64", "jammy"]
- name: "Net::MQTT::Simple" - name: "Net::MQTT::Simple"
version: "1.29" version: "1.29"
- name: "Paws" - 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" 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 no-auto-depends: true
- name: "Statistics::Regression" - name: "Statistics::Regression"
build_distribs: "bullseye" build_names: "bullseye-amd64"
version: "0.53" version: "0.53"
- name: "ZMQ::LibZMQ4" - name: "ZMQ::LibZMQ4"
use_dh_make_perl: "false" use_dh_make_perl: "false"
version: "0.01" version: "0.01"
deb_dependencies: "libzmq5" deb_dependencies: "libzmq5"
build_names: "bullseye-amd64,bookworm,jammy,bullseye-arm64"
name: package ${{ matrix.distrib }} ${{ matrix.arch }} ${{ matrix.name }} name: package ${{ matrix.distrib }} ${{ matrix.arch }} ${{ matrix.name }}
container: container:
image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/${{ matrix.image }}:latest image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/${{ matrix.image }}:latest
@ -395,43 +399,62 @@ jobs:
password: ${{ secrets.HARBOR_CENTREON_PULL_TOKEN }} password: ${{ secrets.HARBOR_CENTREON_PULL_TOKEN }}
steps: steps:
- if: ${{ contains(matrix.build_distribs, matrix.distrib) }} - if: ${{ contains(matrix.build_names, matrix.build_name) }}
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 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 name: Parse distrib name
id: parse-distrib id: parse-distrib
uses: ./.github/actions/parse-distrib uses: ./.github/actions/parse-distrib
with: with:
distrib: ${{ matrix.distrib }} distrib: ${{ matrix.distrib }}
- if: ${{ contains(matrix.build_distribs, matrix.distrib) }} - if: ${{ contains(matrix.build_names, matrix.build_name) }}
name: Get package version name: Get package infos
id: package-version id: package-infos
run: | run: |
apt-get update apt-get update
apt-get install -y cpanminus cpan_info=$(cpanm --info ${{ matrix.name }})
if [ -z "${{ matrix.version }}" ]; then 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 if [[ ! $CPAN_PACKAGE_VERSION =~ ^[0-9]+\.[0-9]+ ]]; then
echo "::error::Invalid version number: ${CPAN_PACKAGE_VERSION}" echo "::error::Invalid version number: ${CPAN_PACKAGE_VERSION}"
exit 1 exit 1
fi fi
PACKAGE_VERSION="${CPAN_PACKAGE_VERSION}" PACKAGE_VERSION="${CPAN_PACKAGE_VERSION}"
else else
PACKAGE_VERSION="${{ matrix.version }}" PACKAGE_VERSION="${{ matrix.version }}"
fi fi
echo "package_version=$(echo $PACKAGE_VERSION)" >> $GITHUB_OUTPUT 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 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: | 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 if [ -z "${{ matrix.deb_dependencies }}" ]; then
PACKAGE_DEPENDENCIES="" PACKAGE_DEPENDENCIES=""
else else
@ -439,30 +462,35 @@ jobs:
PACKAGE_DEPENDENCIES="$PACKAGE_DEPENDENCIES --depends $PACKAGE_DEPENDENCY" PACKAGE_DEPENDENCIES="$PACKAGE_DEPENDENCIES --depends $PACKAGE_DEPENDENCY"
done done
fi fi
if [ ! -z "${{ matrix.no-auto-depends }}" ]; then if [ ! -z "${{ matrix.no-auto-depends }}" ]; then
PACKAGE_DEPENDENCIES="$PACKAGE_DEPENDENCIES --no-auto-depends" PACKAGE_DEPENDENCIES="$PACKAGE_DEPENDENCIES --no-auto-depends"
fi fi
cpanm Module::Build::Tiny temp_file=$(mktemp)
cpanm Module::Install 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
gem install fpm if [ -z "$created_package" ]; then
# Patch to apply fpm fix for debian package generation while waiting for the official fix to be released. echo "Error: fpm command failed"
patch -i .github/patch/fpm-deb.rb.diff $(find / -type f -name "deb.rb") exit 1
fi
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 }} # Check deb
dpkg-deb --contents $created_package || { echo "Error: dpkg-deb failed for package $created_package"; exit 1; }
shell: bash 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: | run: |
apt-get install -y libcurl4-openssl-dev dh-make-perl libssh-dev uuid-dev libczmq-dev libmodule-install-perl libmodule-build-tiny-perl temp_file=$(mktemp)
# module-build-tiny is required for Mojo::IOLoop::Signal build. 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
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 }} 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 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 name: Replace '::' with - in the feature path
id: package-name id: package-name
run: | run: |
@ -472,8 +500,8 @@ jobs:
echo "name_with_dash=$name_with_dash" >> $GITHUB_OUTPUT echo "name_with_dash=$name_with_dash" >> $GITHUB_OUTPUT
shell: bash 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) }}
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with: with:
name: packages-${{ matrix.package_extension }}-${{ matrix.distrib }}-${{ matrix.arch }}-${{ steps.package-name.outputs.name_with_dash}} name: packages-${{ matrix.package_extension }}-${{ matrix.distrib }}-${{ matrix.arch }}-${{ steps.package-name.outputs.name_with_dash}}
path: ./*.${{ matrix.package_extension }} path: ./*.${{ matrix.package_extension }}
@ -491,7 +519,7 @@ jobs:
steps: steps:
- name: Merge Artifacts - name: Merge Artifacts
uses: actions/upload-artifact/merge@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 uses: actions/upload-artifact/merge@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with: with:
name: packages-deb-${{ matrix.distrib }} name: packages-deb-${{ matrix.distrib }}
pattern: packages-deb-${{ matrix.distrib }}-* pattern: packages-deb-${{ matrix.distrib }}-*
@ -519,13 +547,172 @@ jobs:
name: packages-deb-${{ matrix.distrib }} name: packages-deb-${{ matrix.distrib }}
path: ./ path: ./
- uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 - uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with: with:
path: ./*.deb path: ./*.deb
key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }} key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }}
deliver-packages: test-packages:
needs: [get-environment, sign-rpm, download-and-cache-deb] 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: | if: |
needs.get-environment.outputs.skip_workflow == 'false' && 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')) && (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 # set condition to true if artifacts are needed
- if: ${{ false }} - if: ${{ false }}
name: Upload package artifacts name: Upload package artifacts
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with: with:
name: packages-${{ matrix.distrib }}-${{ matrix.arch }} name: packages-${{ matrix.distrib }}-${{ matrix.arch }}
path: ./*.${{ matrix.package_extension}} path: ./*.${{ matrix.package_extension}}

View File

@ -63,7 +63,7 @@ jobs:
cp -r ~/rpmbuild/RPMS/x86_64/*.rpm . cp -r ~/rpmbuild/RPMS/x86_64/*.rpm .
shell: bash shell: bash
- uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 - uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with: with:
path: ./*.rpm path: ./*.rpm
key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
@ -97,7 +97,7 @@ jobs:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 - uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with: with:
path: ./*.rpm path: ./*.rpm
key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} key: unsigned-${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }}
@ -108,7 +108,7 @@ jobs:
- run: rpmsign --addsign ./*.rpm - run: rpmsign --addsign ./*.rpm
shell: bash shell: bash
- uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 - uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with: with:
path: ./*.rpm path: ./*.rpm
key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} 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/ 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 shell: bash
- uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 - uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with: with:
path: ./*.deb path: ./*.deb
key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }} key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }}

View File

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

View File

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

View File

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

View File

@ -208,7 +208,7 @@ jobs:
rpm_gpg_signing_passphrase: ${{ secrets.RPM_GPG_SIGNING_PASSPHRASE }} rpm_gpg_signing_passphrase: ${{ secrets.RPM_GPG_SIGNING_PASSPHRASE }}
stability: ${{ needs.get-environment.outputs.stability }} stability: ${{ needs.get-environment.outputs.stability }}
- uses: actions/cache/save@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 - uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with: with:
path: ./*.${{ matrix.package_extension }} path: ./*.${{ matrix.package_extension }}
key: cache-${{ github.sha }}-${{ matrix.package_extension }}-wsman-${{ matrix.distrib }}-${{ matrix.arch }}-${{ github.head_ref || github.ref_name }} 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 shell: bash
- name: Cache vsphere cli sources - name: Cache vsphere cli sources
uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with: with:
path: vmware-vsphere-cli-distrib path: vmware-vsphere-cli-distrib
key: ${{ github.sha }}-${{ github.run_id }}-sources-perl-vmware-vsphere key: ${{ github.sha }}-${{ github.run_id }}-sources-perl-vmware-vsphere
@ -103,7 +103,7 @@ jobs:
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Import source files - name: Import source files
uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with: with:
path: vmware-vsphere-cli-distrib path: vmware-vsphere-cli-distrib
key: ${{ github.sha }}-${{ github.run_id }}-sources-perl-vmware-vsphere key: ${{ github.sha }}-${{ github.run_id }}-sources-perl-vmware-vsphere

View File

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

View File

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

View File

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

2
.gitignore vendored
View File

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

View File

@ -1,6 +1,13 @@
{ {
"dependencies": [ "dependencies": [
"libboolean-perl",
"libbson-perl",
"libdatetime-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": [ "dependencies": [
"perl(Time::HiRes)",
"perl(DateTime)", "perl(DateTime)",
"perl(MongoDB)",
"perl(Hash::Ordered)", "perl(Hash::Ordered)",
"perl(MongoDB)",
"perl(Time::HiRes)",
"perl(URI::Encode)" "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": [ "dependencies": [
"libsnmp-perl" "libsnmp-perl",
"libdatetime-format-strptime-perl"
] ]
} }

View File

@ -1,5 +1,6 @@
{ {
"dependencies": [ "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} = [ $self->{maps_counters}->{global} = [
{ label => 'scenario-status', { label => 'scenario-status',
type => 2, type => 2,
warning_default => '%{status} !~ "Success"', warning_default => '%{status} =~ /(Aborted|Stopped|Excluded|Degraded)/',
critical_default => '%{status} =~ "Failure"', critical_default => '%{status} =~ "Failure"',
unknown_default => '%{status} =~ /(Unknown|No execution)/',
set => { set => {
key_values => [ { name => 'status' }, { name => 'num_status' }, { name => 'display' } ], key_values => [ { name => 'status' }, { name => 'num_status' }, { name => 'display' } ],
closure_custom_output => $self->can('custom_status_output'), closure_custom_output => $self->can('custom_status_output'),
@ -133,7 +134,7 @@ sub check_options {
my ($self, %options) = @_; my ($self, %options) = @_;
$self->SUPER::check_options(%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 = { my $status_mapping = {
@ -220,20 +221,24 @@ Check ip-label Ekara scenarios.
=item B<--timeframe> =item B<--timeframe>
Set timeframe period in seconds. (default: 900) Set timeframe period in seconds. (default: 7500)
Example: --timeframe='3600' will check the last hour 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> =item B<--filter-type>
Filter by scenario type. Filter by scenario type.
Can be: 'WEB', 'HTTPR', 'BROWSER PAGE LOAD' 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> =item B<--warning-scenario-status>
Warning threshold for scenario status (default: '%{status} !~ "Success"'). Warning threshold for scenario status (default: C<%{status} !~ /(Aborted|Stopped|Excluded|Degraded)/>).
Syntax: --warning-scenario-status='%{status} =~ "xxx"' Syntax: C<--warning-scenario-status='%{status} =~ "xxx"'>
=item B<--critical-scenario-status> =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> =item B<--threshold-value>
Define the scope to which the numeric thresholds apply. 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> =item B<--warning-string>

View File

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

View File

@ -116,7 +116,7 @@ Can use special variables like: %{status}, %{display}
=item B<--critical-*> =item B<--critical-*>
Define the conditions to match for the status to be CRITICAL. (default: %{status} =~ /red/). 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} 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->{version} = '0.1';
$self->{modes} = { $self->{modes} = {
'cpu' => 'network::cyberoam::snmp::mode::cpu', 'cpu' => 'network::cyberoam::snmp::mode::cpu',
'ha-status' => 'network::cyberoam::snmp::mode::hastatus',
'interfaces' => 'snmp_standard::mode::interfaces', 'interfaces' => 'snmp_standard::mode::interfaces',
'license' => 'network::cyberoam::snmp::mode::license',
'list-interfaces' => 'snmp_standard::mode::listinterfaces', 'list-interfaces' => 'snmp_standard::mode::listinterfaces',
'list-vpns' => 'network::cyberoam::snmp::mode::listvpns',
'memory' => 'network::cyberoam::snmp::mode::memory', 'memory' => 'network::cyberoam::snmp::mode::memory',
'requests' => 'network::cyberoam::snmp::mode::requests', 'requests' => 'network::cyberoam::snmp::mode::requests',
'services' => 'network::cyberoam::snmp::mode::services', '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; 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 { sub custom_expires_threshold {
my ($self, %options) = @_; my ($self, %options) = @_;
@ -95,7 +107,17 @@ sub set_counters {
closure_custom_perfdata => $self->can('custom_expires_perfdata'), closure_custom_perfdata => $self->can('custom_expires_perfdata'),
closure_custom_threshold_check => $self->can('custom_expires_threshold') 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}, name => $options{name},
status => $options{entry}->{status} 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})) { if (defined($options{entry}->{expires})) {
$self->{licenses}->{ $options{name} }->{expires_seconds} = $options{entry}->{expires} - time(); $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); $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> =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-*> =item B<--warning-*> B<--critical-*>
Thresholds. Thresholds.
Can be: 'expires'. Can be: 'expires', 'last-update'
=back =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->{version} = '0.1';
%{$self->{modes}} = ( %{$self->{modes}} = (
'cpu' => 'network::moxa::switch::snmp::mode::cpu', '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', 'list-interfaces' => 'snmp_standard::mode::listinterfaces',
'memory' => 'network::moxa::switch::snmp::mode::memory', 'memory' => 'network::moxa::switch::snmp::mode::memory',
'uptime' => 'snmp_standard::mode::uptime', 'uptime' => 'snmp_standard::mode::uptime',

View File

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