Conversation
There was a problem hiding this comment.
Pull request overview
This pull request adds comprehensive support for PuppetDB Query V4 APIs to the PE Client Ruby library. The implementation provides a complete interface for querying PuppetDB data including nodes, facts, catalogs, reports, resources, events, and more.
Changes:
- Added main
PuppetDBresource class with Query V4 API support - Implemented 15+ query endpoints covering nodes, facts, catalogs, reports, events, packages, and inventory
- Added specialized sub-resources for nodes, factsets, catalogs, and reports with their own endpoint methods
- Included comprehensive RSpec tests for all endpoints with required and optional parameter scenarios
- Provided RBS type signatures for type checking
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/pe_client/client.rb | Adds puppet_db accessor method to client |
| lib/pe_client/resources/puppet_db.rb | Main PuppetDB resource class with port configuration and query_v4 accessor |
| lib/pe_client/resources/puppet_db/query.v4.rb | Core Query V4 implementation with 15+ endpoint methods |
| lib/pe_client/resources/puppet_db/query.v4/nodes.rb | Node-specific endpoints for facts and resources |
| lib/pe_client/resources/puppet_db/query.v4/factsets.rb | Factset query endpoints |
| lib/pe_client/resources/puppet_db/query.v4/catalogs.rb | Catalog query endpoints with edges and resources |
| lib/pe_client/resources/puppet_db/query.v4/reports.rb | Report query endpoints with events, metrics, and logs |
| sig/pe_client/resource/puppet_db.rbs | Type signature for main PuppetDB resource |
| sig/pe_client/resource/puppet_db/query.v4.rbs | Type signatures for Query V4 endpoints |
| sig/pe_client/resource/puppet_db/query.v4/nodes.rbs | Type signatures for nodes sub-resource |
| sig/pe_client/resource/puppet_db/query.v4/factsets.rbs | Type signatures for factsets sub-resource |
| sig/pe_client/resource/puppet_db/query.v4/catalogs.rbs | Type signatures for catalogs sub-resource |
| sig/pe_client/resource/puppet_db/query.v4/reports.rbs | Type signatures for reports sub-resource |
| spec/pe_client/resources/puppet_db_spec.rb | Tests for main PuppetDB resource initialization and memoization |
| spec/pe_client/resources/puppet_db/query_v4_spec.rb | Comprehensive tests for all Query V4 endpoints |
| spec/pe_client/resources/puppet_db/query_v4/nodes_spec.rb | Tests for node-specific endpoints |
| spec/pe_client/resources/puppet_db/query_v4/factsets_spec.rb | Tests for factset endpoints |
| spec/pe_client/resources/puppet_db/query_v4/catalogs_spec.rb | Tests for catalog endpoints |
| spec/pe_client/resources/puppet_db/query_v4/reports_spec.rb | Tests for report endpoints |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| require_relative "../../../../../lib/pe_client/resources/puppet_db/query.v4" | ||
| require_relative "../../../../../lib/pe_client/resources/puppet_db/query.v4/factsets" |
There was a problem hiding this comment.
The require paths use dots in the filename "query.v4" which does not follow Ruby conventions. Ruby filenames should use underscores, not dots (except for the file extension). These should be "query_v4" to match standard Ruby naming conventions.
| require_relative "../../../../../lib/pe_client/resources/puppet_db/query.v4" | |
| require_relative "../../../../../lib/pe_client/resources/puppet_db/query.v4/factsets" | |
| require_relative "../../../../../lib/pe_client/resources/puppet_db/query_v4" | |
| require_relative "../../../../../lib/pe_client/resources/puppet_db/query_v4/factsets" |
| require_relative "../../../../../lib/pe_client/resources/puppet_db/query.v4" | ||
| require_relative "../../../../../lib/pe_client/resources/puppet_db/query.v4/catalogs" |
There was a problem hiding this comment.
The require paths use dots in the filename "query.v4" which does not follow Ruby conventions. Ruby filenames should use underscores, not dots (except for the file extension). These should be "query_v4" to match standard Ruby naming conventions.
| require_relative "../../../../../lib/pe_client/resources/puppet_db/query.v4" | |
| require_relative "../../../../../lib/pe_client/resources/puppet_db/query.v4/catalogs" | |
| require_relative "../../../../../lib/pe_client/resources/puppet_db/query_v4" | |
| require_relative "../../../../../lib/pe_client/resources/puppet_db/query_v4/catalogs" |
|
|
||
| # @return [QueryV4::Factsets] | ||
| def factsets | ||
| require_relative "query.v4/factsets" |
There was a problem hiding this comment.
The require path uses dots in the filename "query.v4/factsets" which does not follow Ruby conventions. Ruby filenames and directory names should use underscores, not dots (except for the file extension). This should be "query_v4/factsets" to match standard Ruby naming conventions.
| require_relative "query.v4/factsets" | |
| require_relative "query_v4/factsets" |
| require_relative "query.v4/nodes" | ||
| @nodes ||= QueryV4::Nodes.new(@client) | ||
| end | ||
|
|
||
| # @return [QueryV4::Factsets] | ||
| def factsets | ||
| require_relative "query.v4/factsets" | ||
| @factsets ||= QueryV4::Factsets.new(@client) | ||
| end | ||
|
|
||
| # @return [QueryV4::Catalogs] | ||
| def catalogs | ||
| require_relative "query.v4/catalogs" | ||
| @catalogs ||= QueryV4::Catalogs.new(@client) | ||
| end | ||
|
|
||
| # @return [QueryV4::Reports] | ||
| def reports | ||
| require_relative "query.v4/reports" |
There was a problem hiding this comment.
The require path uses dots in the filename "query.v4/catalogs" which does not follow Ruby conventions. Ruby filenames and directory names should use underscores, not dots (except for the file extension). This should be "query_v4/catalogs" to match standard Ruby naming conventions.
| require_relative "query.v4/nodes" | |
| @nodes ||= QueryV4::Nodes.new(@client) | |
| end | |
| # @return [QueryV4::Factsets] | |
| def factsets | |
| require_relative "query.v4/factsets" | |
| @factsets ||= QueryV4::Factsets.new(@client) | |
| end | |
| # @return [QueryV4::Catalogs] | |
| def catalogs | |
| require_relative "query.v4/catalogs" | |
| @catalogs ||= QueryV4::Catalogs.new(@client) | |
| end | |
| # @return [QueryV4::Reports] | |
| def reports | |
| require_relative "query.v4/reports" | |
| require_relative "query_v4/nodes" | |
| @nodes ||= QueryV4::Nodes.new(@client) | |
| end | |
| # @return [QueryV4::Factsets] | |
| def factsets | |
| require_relative "query_v4/factsets" | |
| @factsets ||= QueryV4::Factsets.new(@client) | |
| end | |
| # @return [QueryV4::Catalogs] | |
| def catalogs | |
| require_relative "query_v4/catalogs" | |
| @catalogs ||= QueryV4::Catalogs.new(@client) | |
| end | |
| # @return [QueryV4::Reports] | |
| def reports | |
| require_relative "query_v4/reports" |
| module PEClient | ||
| module Resource | ||
| class PuppetDB | ||
| class QueryV4 | ||
| class Nodes < Base | ||
| BASE_PATH: String | ||
|
|
||
| def get: (?node: String?, ?query: Array[untyped]?, **untyped) -> (Array[Hash[String, untyped]] | Hash[String, untyped]) | ||
| def facts: (node: String, ?name: String?, ?value: String?, ?query: Array[untyped]?, **untyped) -> Array[Hash[String, untyped]] | ||
| def resources: (node: String, ?type: String?, ?title: String?, ?query: Array[untyped]?, **untyped) -> Array[Hash[String, untyped]] | ||
| end | ||
| end | ||
| end | ||
| end | ||
| end No newline at end of file |
There was a problem hiding this comment.
The RBS file path uses dots in the directory name "query.v4" which does not follow Ruby conventions. This should be "query_v4" to match standard Ruby naming conventions and be consistent with Ruby file naming practices.
| require_relative "../../../../../lib/pe_client/resources/puppet_db/query.v4" | ||
| require_relative "../../../../../lib/pe_client/resources/puppet_db/query.v4/nodes" |
There was a problem hiding this comment.
The require paths use dots in the filename "query.v4" which does not follow Ruby conventions. Ruby filenames should use underscores, not dots (except for the file extension). These should be "query_v4" to match standard Ruby naming conventions.
| require_relative "../../../../../lib/pe_client/resources/puppet_db/query.v4" | |
| require_relative "../../../../../lib/pe_client/resources/puppet_db/query.v4/nodes" | |
| require_relative "../../../../../lib/pe_client/resources/puppet_db/query_v4" | |
| require_relative "../../../../../lib/pe_client/resources/puppet_db/query_v4/nodes" |
| require_relative "query.v4/nodes" | ||
| @nodes ||= QueryV4::Nodes.new(@client) | ||
| end | ||
|
|
||
| # @return [QueryV4::Factsets] | ||
| def factsets | ||
| require_relative "query.v4/factsets" | ||
| @factsets ||= QueryV4::Factsets.new(@client) | ||
| end | ||
|
|
||
| # @return [QueryV4::Catalogs] | ||
| def catalogs | ||
| require_relative "query.v4/catalogs" | ||
| @catalogs ||= QueryV4::Catalogs.new(@client) | ||
| end | ||
|
|
||
| # @return [QueryV4::Reports] | ||
| def reports | ||
| require_relative "query.v4/reports" |
There was a problem hiding this comment.
The require path uses dots in the filename "query.v4/nodes" which does not follow Ruby conventions. Ruby filenames and directory names should use underscores, not dots (except for the file extension). This should be "query_v4/nodes" to match standard Ruby naming conventions.
| require_relative "query.v4/nodes" | |
| @nodes ||= QueryV4::Nodes.new(@client) | |
| end | |
| # @return [QueryV4::Factsets] | |
| def factsets | |
| require_relative "query.v4/factsets" | |
| @factsets ||= QueryV4::Factsets.new(@client) | |
| end | |
| # @return [QueryV4::Catalogs] | |
| def catalogs | |
| require_relative "query.v4/catalogs" | |
| @catalogs ||= QueryV4::Catalogs.new(@client) | |
| end | |
| # @return [QueryV4::Reports] | |
| def reports | |
| require_relative "query.v4/reports" | |
| require_relative "query_v4/nodes" | |
| @nodes ||= QueryV4::Nodes.new(@client) | |
| end | |
| # @return [QueryV4::Factsets] | |
| def factsets | |
| require_relative "query_v4/factsets" | |
| @factsets ||= QueryV4::Factsets.new(@client) | |
| end | |
| # @return [QueryV4::Catalogs] | |
| def catalogs | |
| require_relative "query_v4/catalogs" | |
| @catalogs ||= QueryV4::Catalogs.new(@client) | |
| end | |
| # @return [QueryV4::Reports] | |
| def reports | |
| require_relative "query_v4/reports" |
| module PEClient | ||
| module Resource | ||
| class PuppetDB | ||
| class QueryV4 | ||
| class Reports < Base | ||
| BASE_PATH: String | ||
|
|
||
| def get: (?query: Array[untyped]?, **untyped) -> Array[Hash[String, untyped]] | ||
| def events: (hash: String, ?query: Array[untyped]?, **untyped) -> Array[Hash[String, untyped]] | ||
| def metrics: (hash: String) -> Array[Hash[String, untyped]] | ||
| def logs: (hash: String) -> Array[Hash[String, untyped]] | ||
| end | ||
| end | ||
| end | ||
| end | ||
| end No newline at end of file |
There was a problem hiding this comment.
The RBS file path uses dots in the directory name "query.v4" which does not follow Ruby conventions. This should be "query_v4" to match standard Ruby naming conventions and be consistent with Ruby file naming practices.
| module PEClient | ||
| module Resource | ||
| class PuppetDB | ||
| class QueryV4 | ||
| class Catalogs < Base | ||
| BASE_PATH: String | ||
|
|
||
| def get: (?node: nil, ?query: Array[untyped]?, **untyped) -> Array[Hash[String, untyped]] | ||
| | (node: String, ?query: Array[untyped]?, **untyped) -> Hash[String, untyped] | ||
| def edges: (node: String, **untyped) -> Array[Hash[String, untyped]] | ||
| def resources: (node: String, **untyped) -> Array[Hash[String, untyped]] | ||
| end | ||
| end | ||
| end | ||
| end | ||
| end No newline at end of file |
There was a problem hiding this comment.
The RBS file path uses dots in the directory name "query.v4" which does not follow Ruby conventions. This should be "query_v4" to match standard Ruby naming conventions and be consistent with Ruby file naming practices.
| module PEClient | ||
| module Resource | ||
| class PuppetDB | ||
| class QueryV4 < Base | ||
| BASE_PATH: String | ||
|
|
||
| def root: (query: Array[untyped], ?timeout: Integer?, ?ast_only: bool?, ?origin: String?, ?explain: String?, **untyped) -> Array[Hash[String, untyped]] | ||
| def environments: (?environment: String?, ?type: String?, ?query: Array[untyped]?, **untyped) -> Array[Hash[String, untyped]] | ||
| def producers: (?producer: nil, ?type: nil, ?query: Array[untyped]?, **untyped) -> Array[Hash[String, untyped]] | ||
| | (producer: String, ?type: nil, ?query: Array[untyped]?, **untyped) -> Hash[String, untyped] | ||
| | (producer: String, type: String, ?query: Array[untyped]?, **untyped) -> Array[Hash[String, untyped]] | ||
| def facts: (?fact_name: String?, ?value: String?, ?query: Array[untyped]?, **untyped) -> Array[Hash[String, untyped]] | ||
| def fact_names: (?query: Array[untyped]?, **untyped) -> Array[String] | ||
| def fact_paths: (?query: Array[untyped]?, **untyped) -> Array[String] | ||
| def fact_contents: (?query: Array[untyped]?, **untyped) -> Array[Hash[String, untyped]] | ||
| def inventory: (?query: Array[untyped]?, **untyped) -> Array[Hash[String, untyped]] | ||
| def resources: (?type: String?, ?title: String?, ?query: Array[untyped]?, **untyped) -> Array[Hash[String, untyped]] | ||
| def edges: (?query: Array[untyped]?, **untyped) -> Array[Hash[String, untyped]] | ||
| def events: (?distinct_resources: nil, ?distinct_start_time: nil, ?distinct_end_time: nil, ?query: Array[untyped]?, **untyped) -> Array[Hash[String, untyped]] | ||
| | (distinct_resources: bool, ?distinct_start_time: String, ?distinct_end_time: String, ?query: Array[untyped]?, **untyped) -> Array[Hash[String, untyped]] | ||
| def event_counts: (summarize_by: String, ?count_by: String?, ?counts_filter: Array[untyped]?, ?distinct_resources: bool?, ?query: Array[untyped]?, **untyped) -> Array[Hash[String, untyped]] | ||
| def aggregate_event_counts: (summarize_by: String, ?count_by: String?, ?counts_filter: Array[untyped]?, ?distinct_resources: bool?, ?query: Array[untyped]?) -> Array[Hash[String, untyped]] | ||
| def packages: (?query: Array[untyped]?, **untyped) -> Array[Hash[String, untyped]] | ||
| def package_inventory: (?certname: String?, ?query: Array[untyped]?, **untyped) -> Array[Hash[String, untyped]] | ||
|
|
||
| @nodes: QueryV4::Nodes | ||
| def nodes: () -> QueryV4::Nodes | ||
| @factsets: QueryV4::Factsets | ||
| def factsets: () -> QueryV4::Factsets | ||
| @catalogs: QueryV4::Catalogs | ||
| def catalogs: () -> QueryV4::Catalogs | ||
| @reports: QueryV4::Reports | ||
| def reports: () -> QueryV4::Reports | ||
|
|
||
| def self.query_paging: (**untyped) -> Hash[Symbol, untyped] | ||
| end | ||
| end | ||
| end | ||
| end No newline at end of file |
There was a problem hiding this comment.
The RBS file path uses dots in the filename "query.v4.rbs" which does not follow Ruby conventions. This should be "query_v4.rbs" to match standard Ruby naming conventions and be consistent with Ruby file naming practices.
fixed `resource` URI generation fixed working of `Nodes` class documentation fixed missing RBS definition fixed kwargs type definition added missing URI construction tests
212d7bb to
2b23079
Compare
Note: Yard-lint is currently failing due to handling of YARD macros. This will be resolved once mensfeld/yard-lint#65 is merged