From eec431c0605f083194a1dfb74879f19940d929cc Mon Sep 17 00:00:00 2001 From: Evan-Adam <152897682+Evan-Adam@users.noreply.github.com> Date: Thu, 3 Jul 2025 16:27:06 +0200 Subject: [PATCH] CTOR-1656-move-centreon-plugins-sudoers-to-centreon-plugin-repository (#5598) Co-authored-by: Kevin Duret --- .../workflows/centreon-plugins-sudoers.yml | 131 ++++++++++++++++++ .../centreon-plugins-sudoers.yaml | 40 ++++++ .../sudoersCentreonPlugins | 6 + tests/apps/nmap/cli/discovery.robot | 33 +++++ tests/centreon/plugins/misc.t | 96 +++++++++++++ tests/resources/resources.resource | 10 ++ 6 files changed, 316 insertions(+) create mode 100644 .github/workflows/centreon-plugins-sudoers.yml create mode 100644 dependencies/centreon-plugins-sudoers/centreon-plugins-sudoers.yaml create mode 100644 dependencies/centreon-plugins-sudoers/sudoersCentreonPlugins create mode 100644 tests/apps/nmap/cli/discovery.robot create mode 100644 tests/centreon/plugins/misc.t diff --git a/.github/workflows/centreon-plugins-sudoers.yml b/.github/workflows/centreon-plugins-sudoers.yml new file mode 100644 index 000000000..a4c586239 --- /dev/null +++ b/.github/workflows/centreon-plugins-sudoers.yml @@ -0,0 +1,131 @@ +name: centreon-plugins-sudoers + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +on: + workflow_dispatch: + pull_request: + paths: + - "dependencies/centreon-plugins-sudoers/**" + push: + branches: + - develop + - master + paths: + - "dependencies/centreon-plugins-sudoers/**" + +env: + module_name: centreon-plugins-sudoers +jobs: + get-environment: + uses: ./.github/workflows/get-environment.yml + + package: + needs: [get-environment] + if: | + needs.get-environment.outputs.skip_workflow == 'false' && + needs.get-environment.outputs.stability != 'stable' + + strategy: + fail-fast: false + matrix: + include: + - image: packaging-plugins-alma8 + distrib: el8 + package_extension: rpm + - image: packaging-plugins-alma9 + distrib: el9 + package_extension: rpm + - image: packaging-plugins-bullseye + distrib: bullseye + package_extension: deb + - image: packaging-plugins-bookworm + distrib: bookworm + package_extension: deb + - image: packaging-plugins-jammy + distrib: jammy + package_extension: deb + - image: packaging-plugins-noble + distrib: noble + package_extension: deb + + runs-on: ubuntu-24.04 + + container: + image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/${{ matrix.image }}:latest + credentials: + username: ${{ secrets.HARBOR_CENTREON_PULL_USERNAME }} + password: ${{ secrets.HARBOR_CENTREON_PULL_TOKEN }} + + name: package ${{ matrix.distrib }} + + steps: + - name: Checkout sources + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Package + uses: ./.github/actions/package-nfpm + with: + nfpm_file_pattern: "dependencies/centreon-plugins-sudoers/centreon-plugins-sudoers.yaml" + distrib: ${{ matrix.distrib }} + package_extension: ${{ matrix.package_extension }} + version: ${{ needs.get-environment.outputs.version }} + release: ${{ needs.get-environment.outputs.release }} + arch: all + commit_hash: ${{ github.sha }} + cache_key: cache-${{ github.run_id }}-${{ matrix.package_extension }}-${{ env.module_name }}-${{ matrix.distrib }} + rpm_gpg_key: ${{ secrets.RPM_GPG_SIGNING_KEY }} + rpm_gpg_signing_key_id: ${{ secrets.RPM_GPG_SIGNING_KEY_ID }} + rpm_gpg_signing_passphrase: ${{ secrets.RPM_GPG_SIGNING_PASSPHRASE }} + stability: ${{ needs.get-environment.outputs.stability }} + + deliver-packages: + needs: [get-environment, package] + if: | + (contains(fromJson('["testing", "unstable"]'), needs.get-environment.outputs.stability) || ( needs.get-environment.outputs.stability == 'stable' && github.event_name != 'workflow_dispatch')) && + ! cancelled() && + ! contains(needs.*.result, 'failure') && + ! contains(needs.*.result, 'cancelled') + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + include: + - distrib: el8 + package_extension: rpm + - distrib: el9 + package_extension: rpm + - distrib: bullseye + package_extension: deb + - distrib: bookworm + package_extension: deb + - distrib: jammy + package_extension: deb + - distrib: noble + package_extension: deb + + name: deliver ${{ matrix.distrib }} + steps: + - name: Checkout sources + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + + - name: Delivery + uses: ./.github/actions/package-delivery + with: + module_name: ${{ env.module_name }} + distrib: ${{ matrix.distrib }} + cache_key: cache-${{ github.run_id }}-${{ matrix.package_extension }}-${{ env.module_name }}-${{ matrix.distrib }} + stability: ${{ needs.get-environment.outputs.stability }} + release_type: ${{ needs.get-environment.outputs.release_type }} + artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }} + + set-skip-label: + needs: [get-environment, deliver-packages] + if: | + needs.get-environment.outputs.skip_workflow == 'false' && + ! cancelled() && + ! contains(needs.*.result, 'failure') && + ! contains(needs.*.result, 'cancelled') + uses: ./.github/workflows/set-pull-request-skip-label.yml diff --git a/dependencies/centreon-plugins-sudoers/centreon-plugins-sudoers.yaml b/dependencies/centreon-plugins-sudoers/centreon-plugins-sudoers.yaml new file mode 100644 index 000000000..9c7591ca6 --- /dev/null +++ b/dependencies/centreon-plugins-sudoers/centreon-plugins-sudoers.yaml @@ -0,0 +1,40 @@ +name: "centreon-plugins-sudoers" +arch: "all" +platform: "linux" +version_schema: "none" +version: "${VERSION}" +release: "${RELEASE}${DIST}" +section: "default" +priority: "optional" +maintainer: "Centreon " +description: | + Sudoers configuration for centreon plugins + Commit: @COMMIT_HASH@ +vendor: "Centreon" +homepage: "https://www.centreon.com" +license: "Apache-2.0" + +contents: + - src: ./sudoersCentreonPlugins + dst: /etc/sudoers.d/centreon-plugins + file_info: + mode: 0600 + +overrides: + rpm: + provides: + - centreon-cwrapper-perl + replaces: + - centreon-cwrapper-perl + depends: + - sudo + deb: + depends: + - sudo + +rpm: + summary: Sudoers configuration for centreon plugins + compression: zstd + signature: + key_file: ${RPM_SIGNING_KEY_FILE} + key_id: ${RPM_SIGNING_KEY_ID} diff --git a/dependencies/centreon-plugins-sudoers/sudoersCentreonPlugins b/dependencies/centreon-plugins-sudoers/sudoersCentreonPlugins new file mode 100644 index 000000000..07c5fbaa4 --- /dev/null +++ b/dependencies/centreon-plugins-sudoers/sudoersCentreonPlugins @@ -0,0 +1,6 @@ +User_Alias CENTREON_COLLECT_USERS=centreon-engine,centreon-gorgone +Defaults:CENTREON_COLLECT_USERS !requiretty + +CENTREON_COLLECT_USERS ALL = NOPASSWD: /usr/lib/centreon/plugins/centreon_protocol_dhcp.pl * +CENTREON_COLLECT_USERS ALL = NOPASSWD: /usr/lib/centreon/plugins/centreon_protocol_udp.pl * +CENTREON_COLLECT_USERS ALL = NOPASSWD: /usr/lib/centreon/plugins/centreon_nmap_cli.pl * diff --git a/tests/apps/nmap/cli/discovery.robot b/tests/apps/nmap/cli/discovery.robot new file mode 100644 index 000000000..cb47a15ad --- /dev/null +++ b/tests/apps/nmap/cli/discovery.robot @@ -0,0 +1,33 @@ +*** Settings *** +Documentation Test the Podman container-usage mode +Library Collections + +Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource + +Test Timeout 120s + +*** Variables *** +${MOCKOON_JSON} ${CURDIR}${/}podman.json + +${cmd} ${CENTREON_PLUGINS} +... --plugin=apps::nmap::cli::plugin +... --mode=discovery + +*** Test Cases *** +Container usage ${tc} + [Documentation] Check nmap discovery + [Tags] apps nmap + Log To Console \n + ${command} Catenate + ... ${cmd} + ... --subnet='127.0.0.1/32' + ... ${extraoptions} + + Ctn Run Command And Check Result As Json ${command} ${expected_result} + + Examples: tc extraoptions expected_result -- + ... 1 ${EMPTY} {"end_time":1747232859,"discovered_items":1,"results":[{"hostname":"localhost","ip":"127.0.0.1","hostnames":[{"type":"PTR","name":"localhost"}],"vendor":null,"status":"up","addresses":[{"address":"127.0.0.1","type":"ipv4"}],"os_accuracy":null,"os":null,"services":null,"type":"unknown"}],"duration":0,"start_time":1747232859} + ... 2 --nmap-options='-sS -sU -R -O --osscan-limit --osscan-guess -p U:161,162,T:21-25,80,139,443,3306,5985,5986,8080,8443 -oX - ' {"end_time":1747232859,"discovered_items":1,"results":[{"hostname":"localhost","ip":"127.0.0.1","hostnames":[{"type":"PTR","name":"localhost"}],"vendor":null,"status":"up","addresses":[{"address":"127.0.0.1","type":"ipv4"}],"os_accuracy":null,"os":null,"services":null,"type":"unknown"}],"duration":1,"start_time":1747232859} + ... 3 --nmap-options='-sS -oX - ' {"results":[{"ip":"127.0.0.1","type":"unknown","os_accuracy":null,"status":"up","services":null,"hostnames":[{"type":"PTR","name":"localhost"}],"os":null,"hostname":"localhost","vendor":null,"addresses":[{"address":"127.0.0.1","type":"ipv4"}]}],"duration":0,"discovered_items":1,"start_time":1747234100,"end_time":1747234100} + +*** Keywords *** diff --git a/tests/centreon/plugins/misc.t b/tests/centreon/plugins/misc.t new file mode 100644 index 000000000..6171ff8da --- /dev/null +++ b/tests/centreon/plugins/misc.t @@ -0,0 +1,96 @@ +use strict; +use warnings; +use Test2::V0; +use Test2::Tools::Compare qw{is like match}; +use FindBin; +use lib "$FindBin::RealBin/../../../src"; +use centreon::plugins::misc; +use centreon::plugins::output; +use centreon::plugins::options; +# in real world one should use execute(), but as many options are not supported by windows_execute, +# the signature is not coherent, and we want to test everything on this unix_execute() +sub test_unix_execute { + my $mock_output = mock 'centreon::plugins::output'; # this is from Test2::Tools::Mock, included by Test2::V0 + + my $option = centreon::plugins::options->new(); + my $output = centreon::plugins::output->new(options => $option); + + my @tests = ( + { + expect => '"string to" output "$( echo noworking)"', + msg => 'double quote stay when no interpretation', + args => { + command_path => "/bin", + command => 'echo', + command_options => '"string to" output "$( echo noworking)"', + no_shell_interpretation => 1, + } + }, + { + expect => 'string to output noworking', + msg => 'double quote diseapear when interpretation is enabled', + args => { + command_path => "/bin", + command => 'echo', + command_options => '"string to" output "$( echo noworking)"', + } + }, + { + expect => 'stringToOutput adding', + msg => 'interpretation by default active', + args => { + command => 'echo stringToOutput $(echo adding)', + } + }, + { + expect => 'stringToOutput $(echo adding)', + msg => 'interpretation by default active', + args => { + command => 'echo stringToOutput $(echo adding)', + no_shell_interpretation => 1, + } + }, + { + expect => '', + msg => "no error when no argument given to command without interpolation", + args => { + command => 'echo', + no_shell_interpretation => 1, + } + } + + ); + for my $test (@tests) { + my ($stdout, $exit_code) = centreon::plugins::misc::unix_execute( + output => $output, + options => { timeout => 10 }, + no_quit => 1, + %{$test->{args}}, + ); + is($stdout, $test->{expect}, $test->{msg}); + } + + my ($stdout, $exit_code) = centreon::plugins::misc::unix_execute( + output => $output, + options => { timeout => 10 }, + command => 'NoBinary', + command_output => '"string to" output "$( echo noworking)"', + no_shell_interpretation => 1, + no_quit => 1 + ); + like($stdout, qr/Can't exec "NoBinary": No such file or directory at.*/, 'no_quit option always return'); + ($stdout, $exit_code) = centreon::plugins::misc::unix_execute( + output => $output, + options => { timeout => 10 }, + sudo => 1, + command => 'NoBinary', + command_output => '"string to" output "$( echo noworking)"', + no_shell_interpretation => 1, + no_quit => 1 + ); + like($stdout, qr/Can't exec "sudo": No such file or directory at.*/, 'sudo option add sudo binary before command'); + +} + +test_unix_execute(); +done_testing(); diff --git a/tests/resources/resources.resource b/tests/resources/resources.resource index d3c585046..e3e40ee14 100644 --- a/tests/resources/resources.resource +++ b/tests/resources/resources.resource @@ -85,3 +85,13 @@ Ctn Verify Command Output ... Wrong output result for command:\n${command}\n\nObtained:\n${output}\n\nExpected:\n${expected_result}\n ... values=False ... collapse_spaces=True + +Ctn Run Command And Check Result As Json + [Arguments] ${command} ${expected} + Log To Console ${command} + ${output} Run ${command} + ${output} Strip String ${output} + ${json_output}= evaluate json.loads('''${output}''') json + ${json_expected}= evaluate json.loads('''${expected}''') json + Dictionaries Should Be Equal ${json_output} ${json_expected} ignore_keys=['end_time', 'start_time', 'duration'] + Log Dictionary ${json_output} \ No newline at end of file