Puppet 8 modernization: add sensu_pipeline type, fix annotations, drop EOL platforms - #1358
sourabhpatel-sumo wants to merge 23 commits into
Conversation
- Bump module version to 5.12.0 - Update Puppet dependency to >= 8.0.0 - Add AlmaLinux 8/9, Ubuntu 22.04/24.04 support; drop EOL platforms (CentOS 7, Ubuntu 18.04/20.04, Amazon Linux 2018) - Refresh CI workflows with modern actions and Ruby 3.4/Puppet 8 matrix - Replace legacy nodesets with rocky-9-modern, almalinux-9, ubuntu-24.04 - Remove sensu-plugin-ruby system (sensu::plugins class, sensu_plugin type, sensu_gem provider, sensu::repo::community); expand Bonsai asset docs with migration guide - Update README, DESIGN.md, and REFERENCE.md accordingly Signed-off-by: Sourabh Patel <sourabh.patel.ctr@sumologic.com>
Signed-off-by: Sourabh Patel <sourabh.patel.ctr@sumologic.com>
Signed-off-by: Sourabh Patel <sourabh.patel.ctr@sumologic.com>
Update the Windows acceptance workflow to exclude vendor and .git directories when copying modules to the module path. Update the test helper to dynamically determine the PostgreSQL service name based on the backend platform and ensure CA certificates are symlinked on Debian/Ubuntu systems. Signed-off-by: Sourabh Patel <sourabh.patel.ctr@sumologic.com>
- Fix SSL cert copy: create destination directory first with New-Item, then pipe Get-ChildItem | Copy-Item to avoid PowerShell's "Container cannot be copied onto existing leaf item" error with wildcards - Remove --ignore-dependencies from puppet module install calls now that version ranges are correct and Puppet resolves transitive deps - Update puppet-archive to >= 7.0.0 < 8.0.0 (matching fixtures v7.1.0) - Update puppetlabs-chocolatey to >= 9.0.0 < 10.0.0 (matching fixtures v9.0.0) - Replace puppet module install for puppet-windows_env with git clone from voxpupuli/puppet-windows_env v6.1.0: the Forge's highest version is 4.0.1 which declares puppet < 7.0.0, so no Puppet 8 compatible release is available on the Forge Signed-off-by: Sourabh Patel <sourabh.patel.ctr@sumologic.com>
Signed-off-by: Sourabh Patel <sourabh.patel.ctr@sumologic.com>
Signed-off-by: Sourabh Patel <sourabh.patel.ctr@sumologic.com>
hacking Signed-off-by: Sourabh Patel <sourabh.patel.ctr@sumologic.com>
Signed-off-by: Sourabh Patel <sourabh.patel.ctr@sumologic.com>
The logic for unfreezing OpenSSL::SSLContext::DEFAULT_PARAMS is moved to spec/openssl_unfreeze.rb and loaded via RUBYOPT to ensure compatibility with Puppet monkey patches in Ruby 3.3+. Signed-off-by: Sourabh Patel <sourabh.patel.ctr@sumologic.com>
Ensures `OpenSSL::SSL::SSLContext::DEFAULT_PARAMS` is unfrozen by hooking `Kernel#require`. This prevents `Gem::LoadError` when loaded via `RUBYOPT` by ensuring the fix applies regardless of which component first activates the openssl gem. Signed-off-by: Sourabh Patel <sourabh.patel.ctr@sumologic.com>
Signed-off-by: Sourabh Patel <sourabh.patel.ctr@sumologic.com>
Update annotations to use `HashProperty` instead of `HashOfStringsProperty` to support strings, arrays, and nested hashes. Added validation to ensure keys are non-empty strings or symbols and ensure consistent string keys via munging. Signed-off-by: Sourabh Patel <sourabh.patel.ctr@sumologic.com>
Signed-off-by: Sourabh Patel <sourabh.patel.ctr@sumologic.com>
- Disable BEAKER_debug and set log_level to warn across all test suites - Rename modern OS nodesets to standard naming (e.g., rocky-9-modern to rocky-9) - Update matrix definitions in acceptance workflows to match new naming Signed-off-by: Sourabh Patel <sourabh.patel.ctr@sumologic.com>
Signed-off-by: Sourabh Patel <sourabh.patel.ctr@sumologic.com>
sarvodaya-kumar-26
left a comment
There was a problem hiding this comment.
Code Review
Solid modernization PR — tests are comprehensive and the scope is well-documented. Found a few issues worth addressing before merge, ranging from a potential data-loss risk to minor code quality items.
ReviewThanks for taking this on — the module is unusable on Puppet 8 today and this fixes that. The Reviewed at 211 files, +4,122 / −4,980. I read the non-spec diff in full and checked the new Sensu fields against the Blocking1.
|
| Removed | Status on master |
|---|---|
sensu::plugins |
Public, REFERENCE.md:1118, ~90 lines of README with six worked examples |
sensu_plugin type |
Public, REFERENCE.md:4070 + six documented parameters |
sensu_gem package provider |
Public (package { provider => sensu_gem }) |
None of these carry a deprecation warning on master. The description says the mechanism is "deprecated," but that's not signalled in code — a user on 5.11.1 gets no warning, then a compilation failure on 5.12.0. This project's pattern has been deprecate-then-remove-at-a-major (v5.0.0 carried #1273 "Remove various deprecations").
Since sensu_bonsai_asset already exists and you've documented the migration at README.md:892, I don't think a deprecation cycle is needed — just bump to 6.0.0 and list the removals. Alternatively, split the PR: Puppet 8 migration as 5.12.0 (urgent, uncontroversial, ships immediately) and the plugin removal as 6.0.0. That would also let the systemd and repo changes bake separately.
tasks/install_agent_windows.ps1 — undisclosed breaking change
$PackageSource becomes Mandatory = $True and the hardcoded MSI URL is removed. Existing Windows task invocations that omit it now fail at parameter binding. The two schemas also disagree: install_agent_windows.json declares String[1] (required) while install_agent.json declares Optional[String[1]].
Missing test coverage for new code
spec/unit/provider/sensu_pipeline/doesn't exist. Two new providers (~135 lines each) ship with zero unit specs, while every other type in the module has them.- No specs anywhere for
puppet_x/sensu/*, despite this PR changinginsync?and addingvalidate/mungetoHashProperty. Those are exactly the changes that want direct tests.
ArrayOfHashesProperty#insync? is order-sensitive
is.map(&strip_nils) == should.map(&strip_nils)pipelines, subdues, and output_metric_thresholds are all semantically sets. If sensuctl returns them in a different order than declared, every run reports drift and re-applies. Suggest sorting by a stable key before comparing.
Dead labels filter in HashProperty#insync?
The sensu.io/managed_by filter added there can't run: all labels properties use HashOfStringsProperty, which already has an identical filter. HashProperty only parents annotations, fallback_pipeline, and subdue. Worth removing so the next reader doesn't assume it's load-bearing.
sensu-backend init lost both its config file and its readiness guard
- 'command' => 'sensu-backend init --config-file /etc/sensu/backend.yml',
- 'require' => 'Sensu_api_validator[sensu]',
+ 'command' => 'sensu-backend init',
+ 'require' => 'Service[sensu-backend]',Without --config-file, init uses its own defaults rather than the managed backend.yml, which diverges as soon as anyone sets config_hash. And the service being started isn't the same as the API being ready — Sensu_api_validator was bridging exactly that gap. This looks like a source of flaky first-run failures.
etcd partial-override footgun
Because all eight etcd keys are now always present in backend.yml, an operator who overrides only etcd-initial-cluster via config_hash silently keeps advertising http://127.0.0.1:2380 as their peer URL. tests/sensu-backend-cluster.pp:16-23 overrides all eight, so acceptance won't catch it. Either omit these keys when unset, or validate that they're set as a group.
sensu_api.rb — nil-URL fallback
uri = url ? URI.join(url, path) : URI("http://localhost#{path}"), three times. A nil URL is a config bug; silently retargeting to plaintext localhost turns a loud failure into a confusing one. Suggest raising.
sensu_user.rb — configure_url default flips http:// → https://
Right direction, but it's an undocumented behavior change. Worth a line in the description.
CI coverage
- The validate step drops
strings:generate reference, so REFERENCE.md drift is no longer enforced in CI. I can see you runstrings:validate:referencelocally and REFERENCE.md is in fact fully in sync in this PR — it's the next PR I'd worry about. - Both
.fixtures-latest.ymlallow-failure jobs are deleted. Collapsing the puppet dimension 4 → 1 is correct now, but those canaries were testing against latest stdlib/postgresql/systemd, not older Puppet. Worth keeping one. parallel_spec→specslows CI and leavesparallel_testsunused in the Gemfile.
Dependency bounds contradict each other
metadata.json pins stdlib >= 9.0.0 < 10.0.0, but tests/provision_basic_el.sh and provision_basic_debian.sh install >= 8.0.0 < 11.0.0. Acceptance can pass against a stdlib version the module declares unsupported.
tests/generate-etcd-ssl.sh — unverified download
curl -sL of cfssl 1.6.5 into /usr/local/bin with no checksum or signature. Test-only, but it's a root-owned binary on a fresh box — a sha256sum -c would be cheap.
Smaller items
parse_yaml_dump's rescue falls back tooutput.split('---').map { YAML.load(d) }— the exact broken behavior being fixed. It'll mangle any document containing---in a value.- Five providers (
sensu_cluster_federation,..._member,sensu_etcd_replicator,sensu_postgres_config,sensu_secrets_vault_provider) inline the dump+parse logic instead of callingdump(), and inconsistently (self.parse_yaml_dumpvsPuppet::Provider::Sensuctl.parse_yaml_dump).dump()still exists, now used once. SENSU_PIPELINE_VALIDATE_REFis a top-level global constant inlib/puppet/type/sensu_pipeline.rb— worth moving inside the type or namespacing.def self.sensuctl(args, failonfail: nil, ..., **_kwargs)— all call sites are migrated correctly, but the catch-all will silently swallow typo'd option names in future ones.URI.escape(name, '/')→name.gsub('/', '%2F')escapes only/. Fine for Bonsai'snamespace/name;URI.encode_www_form_componentis the drop-in if names ever widen..rubocop.ymlsetsTargetRubyVersion: '3.4', but puppet-agent 8 ships Ruby 3.2 — should probably be3.2, or you'll accept syntax the agent can't parse.metadata.jsonremovespdk-version/template-url/template-refwhile.sync.ymlstays. Worth finishing the move away from modulesync or keeping the keys.- The Gemfile drops eight puppet-lint plugins including
legacy_factsandtop_scope_facts— both directly useful for a Puppet 8 migration. - Amazon 2023 is added to the supported-OS list and mapped to
repo_release = '9', butspec/fixtures/facts/amazon-2-x86_64.factsandamazon-2018-x86_64.factsare deleted with no 2023 fixture added, so the new mapping is untested.
Nits
RUN_ACCEPTANCE: 1is set in the acceptance workflows and read nowhere in the repo.acceptance-full'sexclude: {puppet: puppet8, ci_build: yes}is a no-op after the matrix rewrite.fallback_pipelinerequiresname/type/api_versionbut doesn't reject unknown keys, whilepipelinesandsubduesdo. Same shape, different strictness.BEAKER_debug: true→falsewill make CI failures harder to diagnose.- The cluster acceptance set drops
use_agent: yeswithout explanation.
What's good here
- The new
sensu_checkproperties are all real. I checked each againstsensu/corev2/*.proto:subdue = 16,pipelines = 32,output_metric_thresholds = 33,subdues = 34,fallback_pipeline = 35,ttl_status = 36,asset_status = 37, plusPipeline.ContinueOnError = 3. The Puppet property types map correctly to the wire types (ttl_status→Integer for int32,asset_status→Array for repeated string, etc.). Validation is more thorough than it had to be — the nesteddays/day-name checks onsubdueand thethresholds/tagsstructure onoutput_metric_thresholdsare good. Only leniencies:min/maxaren't validated as Strings andrepeatelements aren't type-checked. - Two spec files renamed into existence:
spec/acceptance/sensu_bonsai_asset.rb→_spec.rbandspec/unit/sensu_license.rb→_spec.rb. Those assertions had never run. Nice catch. - REFERENCE.md is genuinely complete and in sync —
subdue(2615),subdues(2629),sensu_pipeline(4091+),continue_on_error(4140), all sevenkeepalive_*, and zero stale references to the removed plugin API. - The README migration note at line 892 pointing
sensu::pluginsusers atsensu_bonsai_assetis the right way to do a removal. - Test certs are valid through Aug 2036 with current CRLs — no hidden expiry cliff.
- Both Ruby shims (
spec/vendor/archive/tar/minitar.rb,spec/openssl_unfreeze.rb) are small, commented, explain why they exist, and are excluded from the published module by.pdkignore. That's the right way to carry a workaround. - Docker image caching +
timeout-minutesin acceptance, and the local-run docs intests/README.md(Apple Siliconuser_agentworkaround,BEAKER_DESTROY=no, corporate CA note) will save the next contributor real time.
Suggested landing path
- Delete the
repo.ppEL8 branch and letyumrepohandleel/8. - Restore
api-url, derived fromuse_ssl. - Drop the hand-rolled systemd unit — or parameterize user/group, namespace the exec, remove the dead
ExecStart, and addagent_spec.rbcoverage. - Add
spec/unit/provider/sensu_pipeline/{sensuctl,sensu_api}_spec.rb. - Bump to
6.0.0and enumerate the removals, or split the plugin removal into its own PR. - Restore
strings:generate referenceto the validate step and keep one.fixtures-latest.ymlcanary.
The pipeline support and the Ruby 3 migration are solid and I'd take them as-is. The systemd and repo changes read more like debugging artifacts that survived into the diff — I'd want those split out and justified separately.
Caveat: I couldn't run the suite locally (no Ruby ≥ 3.2 available on this machine), so all of the above is from static reading plus verification against the sensu/core protos, sensu-go v6.14.2 backend/cmd/start.go, the live packagecloud config file, and Puppet's exec/posix provider. I read the non-spec diff in full; spec and nodeset diffs by diffstat and targeted greps. Review assisted by Claude Code.
Reverts review-flagged regressions (gpg bypass, tls downgrade, systemd conflict) instead of deleting the underlying features.
Splits the breaking removal into its own 6.0.0 PR so this migration can merge on its own at 5.12.0.
spec/openssl_unfreeze.rb only loaded via spec_helper.rb, so strings:generate crashed under CI's openssl 3.3+ build outside of rspec runs. Load it Rakefile-wide instead.
Restores real unit test coverage that's been silently masked for a long time: no committed Gemfile.lock means CI's fresh bundle install could resolve json 3.0+, which breaks facterdb's jgrep dependency (JSON.create_id= was removed). Once past that, default_facter_version '3.11.9' matched nothing in facterdb's Facter 4.x/5.x-only fixtures, so on_supported_os silently returned zero cases for every spec/classes file -- 0 examples, 0 failures, indistinguishable from a clean run. - Gemfile: scope the json < 3.0 pin to development/unit_tests, where rspec-puppet-facts/facterdb actually need it - spec/spec_helper.rb: default_facter_version -> 5.6 (verified 13/13 metadata.json OS/release combos resolve; the one gap, Windows 2016, falls back to 4.4.0 via the existing loose-requirement check) - spec/acceptance/04_plugins_spec.rb: skip -- sensu-plugins-ruby has no package for any currently-supported OS, confirmed failing identically across rocky-9/debian-12/almalinux-9/ubuntu-22.04; removed entirely in the follow-up plugin-removal PR - 6 spec/classes files: facts[:osfamily] -> facts[:os]['family'] -- the legacy flat fact doesn't exist in Facter 4.x/5.x fixture data - 5 spec/classes files: stale RedHat 7 target -> 8 (7 was dropped from metadata.json entirely) With facts actually flowing for the first time, three more gaps surfaced once `rake spec_prep` populated the fixture modules: - spec/classes/repo_spec.rb: missing case branch left redhat-9/rocky-9/ almalinux-9 expecting an undefined baseurl instead of the real el/9 one -- my own gap from the earlier repo.pp revert in this branch - manifests/agent/annotation.pp: value was still typed String, so the "allow mixed types in annotations" fix never actually worked end to end for sensu::agent -- Array/Hash values passed the outer parameter check but still failed one layer deeper. Retyped to match Variant[String, Array, Hash]; agent_spec.rb's validation tests were wrong for the same reason and are corrected alongside it - spec/classes/common_spec.rb: second, unguarded compile check hit the same already-documented rspec-puppet Windows path-mocking limitation (rodjek/rspec-puppet#750) that an earlier check in the same file already works around spec/classes: 2194 examples, 0 failures (excluding the two files plugin-removal deletes outright). spec/unit: still 1523/1523.
Two items from Sarvodaya Kumar's review of #1358 that were still outstanding after the earlier round of fixes. - lib/puppet/provider/sensuctl.rb: bare YAML.load rejects Time/Symbol under Ruby 3.1+/Psych 4+'s safe-by-default loading. Confirmed real: reproduced Psych::DisallowedClass with a plain timestamp-bearing document on this branch's own target Ruby 3.4.10/Psych 5.2.2. sensuctl_auth_types had no rescue at all, so any auth resource with a timestamp field crashed the whole run; parse_yaml_dump's fallback hit the same wall one layer deeper, right where it was meant to recover. YAML.load_stream (the primary path in parse_yaml_dump) is unaffected -- verified it already handles Time permissively, so it's intentionally left alone rather than blanket-patched. Added regression coverage: neither new test fails without the fix reverted (checked), both pass with it. - lib/puppet/type/sensu_pipeline.rb: SENSU_PIPELINE_VALIDATE_REF was a bare top-level constant. Puppet reloads type files repeatedly per compilation, so this logged "already initialized constant" on every reload. Moved under PuppetX::Sensu::Pipeline, matching this module's existing lib/puppet_x/sensu/ convention. spec/unit + spec/classes: 3719 examples, 0 failures.
bundle exec rake parallel_spec (the actual CI command) still failed
even after the earlier facts[:osfamily] round, because these two files
were deliberately skipped there on the reasoning that plugin-removal
deletes them anyway. That reasoning missed that puppet8-modernization
needs its own CI green before plugin-removal ever merges.
- Same facts[:osfamily] -> facts[:os]['family'] fix as the other 6
files (6 occurrences across the two files)
- spec/spec_helper.rb's platforms() helper never had
:plugins_dependencies / :plugins_package_require keys added for
this modernized branch, so plugins_spec.rb crashed with
NoMethodError the moment real facts started flowing. Added them,
matching data/os/{RedHat,Debian}.yaml's actual hiera values and
manifests/plugins.pp's require chain.
- repo_community_spec.rb's case statement was missing rocky-8/
almalinux-8/-9 family branches entirely (only redhat-8/centos-8 and
a pre-2023-Amazon-support amazon regex existed). Added them,
including a comment noting manifests/repo/community.pp itself still
resolves Amazon 2023 to el/7 (unlike the newer repo.pp) -- the test
now matches that actual behavior rather than fixing manifest logic
in a class this branch's follow-up PR deletes outright.
bundle exec rake parallel_spec (exact CI command, no exclusions):
4143 examples, 0 failures.
- Gemfile: rexml stopped being a default gem in Ruby 3.4; only beaker (system_tests) pulled it in, so the Unit job's BUNDLE_WITHOUT=system_tests:development left it missing and crashed chocolatey's package provider autoload during any package-resource compile (e.g. sensu::backend::datastore::postgresql). - sensu_plugin_spec.rb: same dead-package root cause as 04_plugins_spec.rb (no sensu-plugins-ruby package for any supported OS); skip it too since mode=types was never run locally when that file was first skipped. - spec_helper_acceptance.rb: raise docker-api's read/write timeout so the 3-host EL8 cluster nodeset's cold image builds don't exceed beaker-docker's 300s default.
|
@amdprophet @sarvodaya-kumar-26 — pushed updates addressing both reviews:
Let me know if anything needs another look. |
Description
Modernizes the module for Puppet 8 and current OS support. Adds
sensu_pipelineresource typeand pipeline support in
sensu_check. Fixes annotations to accept mixed value types. Drops EOLplatforms.
The
sensu-plugin-rubyremoval originally scoped here has been split into a follow-up,stacked PR targeting
6.0.0(plugin-removal, based on this branch) — it's a breaking changewith no prior deprecation cycle and shouldn't ride along with this otherwise non-breaking
5.12.0release.sensu_bonsai_assetis the documented replacement (README.md).Related Issues
to_yamlfunction replaced withstdlib::to_yamlinbackend.ppsensu_checklackedpipelinesparameter; resolved by addingpipelines/fallback_pipelineproperties and newsensu_pipelinetypeMotivation and Context
Puppet 6/7 and the previously supported OS platforms are EOL.
Breaking / behavior changes
sensu_user'sconfigure_urldefault changed fromhttp://tohttps://. Asensu_userresource that doesn't set
configure_urlexplicitly (outsidesensu::backend, which alreadyderives it correctly from
use_ssl) will now attempt HTTPS. Onuse_ssl => falsedeploymentsthis will fail unless
configure_urlis set explicitly.tasks/install_agent_windows.ps1's$PackageSourceno longer has a hardcoded fallback MSIURL (the old default pointed at a stale Sensu Go 5.13.1 build) — it must now be supplied, and
fails with a clear error if it's missing rather than a stale silent default.
appveyor.ymlis removed (CI has moved to GitHub Actions);.pdkignore/.sync.ymlupdatedto match.
How Has This Been Tested?
bundle exec rake sensu_validate lint strings:generate reference— passes cleanbundle exec rake spec— 3719 examples, 0 failures (spec/unit+spec/classes)rocky-9base mode — clean exceptsensu::plugins, which isskip-marked (see below)rocky-8-cluster— 24 examples, 0 failures (exercises the EL8repo.pppath specifically)debian-12base mode — 77 examples, 0 failures, 14 pendingsensu::pluginsacceptance coverage (spec/acceptance/04_plugins_spec.rb) is intentionallyskip-marked: the legacypackagecloud.io/sensu/communityrepo has nosensu-plugins-rubypackage for any OS this module currently supports — confirmed failing identically across
rocky-9/debian-12/almalinux-9/ubuntu-22.04. This is exactly why the subsystem is being removed
in the follow-up PR rather than fixed here.
General
README.mdwith any necessary configuration snippetsbundle exec rake sensu_validate lint spec