### Setup Development Environment Source: https://github.com/voxpupuli/pypuppetdb/blob/master/CONTRIBUTING.md Installs necessary packages and sets up the project in development mode. Ensure you have Python 3 and virtualenv installed. ```bash # Create a Python 3 virtualenv and activate it virtualenv -p python3 .venv . .venv/bin/activate # Get the up to date base packages pip install --upgrade wheel setuptools # Install the module in a development mode python setup.py develop # Install/update test dependencies pip install --upgrade -r requirements-test.txt ``` -------------------------------- ### Install pypuppetdb Source: https://github.com/voxpupuli/pypuppetdb/blob/master/README.md Install the pypuppetdb package using pip. This command is used for setting up the library. ```bash pip install pypuppetdb ``` -------------------------------- ### PQL Queries Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Examples of using PQL (Puppet Query Language) to query facts and reports from PuppetDB. ```APIDOC ## PQL Queries ### Description Examples of using PQL (Puppet Query Language) to query facts and reports from PuppetDB. ### PQL for facts ```python for fact in db.pql('facts { name = "ipaddress" }'): print(fact.node, fact.value) ``` ### PQL for reports ```python for report in db.pql('reports { latest_report? = true }'): print(report.hash_, report.status, report.run_time) ``` ``` -------------------------------- ### Build Documentation Locally Source: https://github.com/voxpupuli/pypuppetdb/blob/master/CONTRIBUTING.md Installs documentation dependencies and builds the HTML documentation. This requires activating the virtual environment used for app development. ```bash # Activate the virtualenv used for the app development pip install --upgrade -r docs/requirements.txt cd docs make html ``` -------------------------------- ### Get Resources by Type Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/basics.md Retrieves all resources of a specific type, like 'file'. Be cautious with large infrastructures as this can return a huge amount of data. ```python >>> resources = db.resources('file') ``` -------------------------------- ### Get Catalog for Host Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/basics.md Retrieves the latest catalog for a specified host. The catalog contains all defined resources and their relationships. ```python >>> catalog = db.catalog('hostname') >>> for res in catalog.get_resources(): >>> print(res) ``` -------------------------------- ### Get Resource Relationships Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/basics.md Retrieves all relationships for a specific resource within a host's catalog. This shows how resources are linked. ```python >>> catalog = db.catalog('hostname') >>> resource = catalog.get_resource('Service', 'ntp') >>> for rel in resource.relationships: >>> print(rel) Class[Ntp] - contains - Service[ntp] File[/etc/ntp.conf] - notifies - Service[ntp] File[/etc/ntp.conf] - required-by - Service[ntp] ``` -------------------------------- ### Build AST Query for Nodes with Fact Filters Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/advanced_queries.md Use QueryBuilder to construct a query that extracts certnames for nodes matching specific fact values. This example demonstrates chaining operators like InOperator, ExtractOperator, and SubqueryOperator. ```python >>> from pypuppetdb.QueryBuilder import * >>> op = InOperator('certname') >>> query = ExtractOperator() >>> query.add_field(str('certname')) >>> subquery = SubqueryOperator('facts') >>> _add = AndOperator() >>> _add.add(EqualsOperator('name', 'operatingsystem')) >>> _add.add(EqualsOperator('value', 'Debian')) >>> subquery.add_query(_add) >>> query.add_query(subquery) >>> op.add_query(query) >>> print(op) ["in", "certname", ["extract", ["certname"], ["select_facts", ["and", ["=", "name", "operatingsystem"], ["=", "value", "Debian"]]]]] >>> nodes = db.nodes(query=query) >>> for node in nodes: >>> print(node.name) foo.example.com bar.example.com ``` -------------------------------- ### Get All Nodes Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/basics.md Retrieves a generator for all nodes from PuppetDB. Use this when you need to iterate over all known nodes. ```python >>> nodes = db.nodes() >>> for node in nodes: >>> print(node) host1 host2 ... ``` -------------------------------- ### Get Single Node Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/basics.md Retrieves a specific node by its hostname. Useful for fetching details of a single machine. ```python >>> node = db.node('hostname') >>> print(node) hostname ``` -------------------------------- ### Get Node Fact Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/basics.md Retrieves a specific fact for a given node. This scopes the query to a single node. ```python >>> node = db.node('hostname') >>> print(node.fact('osfamily').value) RedHat ``` -------------------------------- ### Build AST Query with Subquery on Events Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/advanced_queries.md Create a query using SubqueryOperator to filter nodes based on event status. This example demonstrates selecting events with a 'noop' status. ```python >>> from pypuppetdb.QueryBuilder import * >>> op = InOperator('certname') >>> ex = ExtractOperator() >>> ex.add_field(str('certname')) >>> sub = SubqueryOperator('events') >>> sub.add_query(EqualsOperator('status', 'noop')) >>> ex.add_query(sub) >>> op.add_query(ex) >>> print(op) ["in","certname",["extract",["certname"],["select_events",["=", "status", "noop"]]]] ``` -------------------------------- ### Get Facts by Name Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/basics.md Retrieves all known values for a specific fact across all nodes. Useful for aggregating fact data. ```python >>> facts = db.facts('osfamily') >>> for fact in facts: >>> print(f"{fact.node} - {fact.value}") host1 - RedHat host2 - Debian ``` -------------------------------- ### Query reports and events Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Retrieve reports for a specific node, ordered by time, and iterate through their associated events. You can also query events directly or get summarized event counts. ```python from pypuppetdb import connect from pypuppetdb.QueryBuilder import EqualsOperator, AndOperator, GreaterOperator import datetime db = connect() # Recent reports for a specific node, ordered newest-first import json order = json.dumps([{"field": "end_time", "order": "desc"}]) for report in db.reports( query=EqualsOperator("certname", "web01.example.com"), limit=10, order_by=order, ): print(report.hash_, report.status) # "abc123... changed" print(report.start, report.end) # datetime objects print(report.run_time) # timedelta print(report.agent_version, report.environment) # Iterate events within this report for event in report.events(): print(event) # "File[/etc/ntp.conf]/abc123..." print(event.status, event.failed) # "success", False print(event.item["old"], "->", event.item["new"]) # Query events directly with a filter for event in db.events( query=EqualsOperator("certname", "web01.example.com"), limit=50, ): print(event.node, event.item["type"], event.item["title"]) # Event counts summarized by certname counts = db.event_counts(summarize_by="certname", query=EqualsOperator("latest_report?", True)) for c in counts: print(c) # Aggregate event counts across the infrastructure agg = db.aggregate_event_counts(summarize_by="certname") print(agg) # {"successes": 42, "failures": 3, "noops": 1, "skips": 0} ``` -------------------------------- ### Connect to PuppetDB (Default) Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/connecting.md Use this when running the code on the same host as PuppetDB with default configurations. Imports the connect function and establishes a connection. ```python from pypuppetdb import connect db = connect() ``` -------------------------------- ### Prepare a Release Source: https://github.com/voxpupuli/pypuppetdb/blob/master/CONTRIBUTING.md Steps for preparing a new release using tbump. This involves updating the changelog and running the release command. ```bash # Add entry to the CHANGELOG.md / verify that it contains all the changes. # Run tbump # Edit the release created in GitHub - if needed correct the type (final/prerelease), update the description with a changelog fragment. ``` -------------------------------- ### PQL Queries for Facts and Reports Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Demonstrates how to use PQL to query for fact objects and report objects from PuppetDB. ```python for fact in db.pql('facts { name = "ipaddress" }'): print(fact.node, fact.value) ``` ```python for report in db.pql('reports { latest_report? = true }'): print(report.hash_, report.status, report.run_time) ``` -------------------------------- ### Execute Puppet Query Language (PQL) Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Run PQL queries against the PuppetDB API. Results are automatically cast to rich types for supported entities, or returned as plain dictionaries if projections are used. ```python from pypuppetdb import connect db = connect() # PQL query → returns Node objects nodes = db.pql(""" nodes { facts { name = "operatingsystem" and value = "Debian" } } """) for node in nodes: print(node.name, node.status) # PQL with status enrichment for nodes nodes = db.pql( 'nodes { certname ~ "web" }', with_status=True, unreported=2, ) for node in nodes: print(node.name, node.status) # PQL with projection → returns plain dicts results = db.pql(""" nodes[certname, report_environment] { certname ~ "db" } """) for r in results: print(r["certname"], r["report_environment"]) ``` -------------------------------- ### connect() - Establish a connection to PuppetDB Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Establishes a connection to PuppetDB and returns an API object. Supports various authentication methods and can be used as a context manager. ```APIDOC ## connect() ### Description Establishes a connection to PuppetDB and returns an `API` object used for all subsequent operations. Supports plain HTTP, mutual TLS, RBAC token auth, and HTTP Basic Auth. Use as a context manager to guarantee connection cleanup. ### Method `connect()` ### Parameters - **host** (string) - Optional - The hostname or IP address of the PuppetDB server. - **port** (int) - Optional - The port number for the PuppetDB server (default: 8080). - **ssl_key** (string) - Optional - Path to the client's private key file for mutual TLS. - **ssl_cert** (string) - Optional - Path to the client's certificate file for mutual TLS. - **ssl_verify** (string or bool) - Optional - Path to the CA certificate file for verification, or False to disable verification. - **token** (string) - Optional - RBAC token for authentication. - **username** (string) - Optional - Username for HTTP Basic Auth. - **password** (string) - Optional - Password for HTTP Basic Auth. - **protocol** (string) - Optional - The protocol to use (e.g., 'http' or 'https'). - **url_path** (string) - Optional - The base path for the PuppetDB API if not at the root. ### Request Example ```python from pypuppetdb import connect db = connect( host="puppetdb.example.com", port=8081, ssl_key="/path/to/private.pem", ssl_cert="/path/to/public.pem", ssl_verify="/path/to/ca_crt.pem", ) with connect(host="puppetdb.example.com", port=8081, ssl_verify=False) as db: pass ``` ### Response - **API object** - An object used for subsequent operations. ``` -------------------------------- ### QueryBuilder: Binary Operators Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Illustrates the use of binary operators like EqualsOperator, RegexOperator, and NullOperator for constructing query conditions. ```python print(EqualsOperator("environment", "production")) ``` ```python print(RegexOperator("certname", r"web\d+\.example\.com")) ``` ```python print(NullOperator("deactivated", False)) ``` ```python cutoff = datetime.datetime(2024, 1, 1) print(GreaterOperator("report_timestamp", cutoff)) ``` -------------------------------- ### AST Query for Node Certnames Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/advanced_queries.md Use the `nodes()` method with the `query` parameter to perform AST queries. This method is an alternative to PQL for constructing queries programmatically. ```python >>> nodes = db.nodes(query=""" ["subquery", "facts", ["and", ["=", "name", "operatingsystem"], ["=", "value", "Debian"] ] ] """) >>> for node in nodes: >>> print(node.name) foo.example.com bar.example.com ``` -------------------------------- ### Build AST Query for Nodes in Production Environment Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/advanced_queries.md Construct a query to find nodes belonging to the 'production' environment using AndOperator to combine environment checks for catalog and facts. ```python >>> from pypuppetdb.QueryBuilder import * >>> op = AndOperator() >>> op.add(EqualsOperator('catalog_environment', 'production')) >>> op.add(EqualsOperator('facts_environment', 'production')) >>> print(op) ["and",["=", "catalog_environment", "production"],["=", "facts_environment", "production"]] ``` -------------------------------- ### Execute PQL Queries Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Run raw Puppet Query Language (PQL) strings against the PuppetDB API. This method supports automatic casting of results to rich object types or returning plain dictionaries. ```APIDOC ## `db.pql()` — Puppet Query Language (PQL) Executes a PQL string against the `pdb/query/v4` endpoint. Automatically casts results to rich types (`Node`, `Report`, `Fact`, etc.) when the query targets a supported entity without field projections. ```python from pypuppetdb import connect db = connect() # PQL query → returns Node objects nodes = db.pql(""" nodes { facts { name = "operatingsystem" and value = "Debian" } } """) for node in nodes: print(node.name, node.status) # PQL with status enrichment for nodes nodes = db.pql( 'nodes { certname ~ "web" }', with_status=True, unreported=2, ) for node in nodes: print(node.name, node.status) # PQL with projection → returns plain dicts results = db.pql(""" nodes[certname, report_environment] { certname ~ "db" } """) for r in results: print(r["certname"], r["report_environment"]) ``` ``` -------------------------------- ### Connect to PuppetDB Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Establishes a connection to PuppetDB. Supports plain HTTP, mutual TLS, RBAC token auth, and HTTP Basic Auth. Use as a context manager for automatic cleanup. ```python from pypuppetdb import connect # Plain connection to localhost (default port 8080) db = connect() # Remote host with mutual TLS (client cert + CA verification) db = connect( host="puppetdb.example.com", port=8081, ssl_key="/path/to/private.pem", ssl_cert="/path/to/public.pem", ssl_verify="/path/to/ca_crt.pem", ) # Puppet Enterprise RBAC token (auto-switches to HTTPS) db = connect( host="puppetdb.example.com", port=8081, token="myRbacToken", ssl_verify=False, # disable cert check if needed ) # HTTP Basic Auth via a reverse proxy db = connect( protocol="https", host="puppetdb.example.com", port=443, username="foo", password="bar", url_path="/puppetdb", # if PuppetDB is not at / ) # Context-manager form (connections closed automatically) with connect(host="puppetdb.example.com", port=8081, ssl_key="/path/to/private.pem", ssl_cert="/path/to/public.pem", ssl_verify="/path/to/ca_crt.pem") as db: for node in db.nodes(): print(node.name) # Explicit disconnect db = connect() try: print(list(db.nodes())) finally: db.disconnect() ``` -------------------------------- ### Build AST Query Accessing Different Entities with FromOperator Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/advanced_queries.md Demonstrates using FromOperator to query across different entities, specifically accessing fact contents to find nodes with a specific network MAC address. ```python >>> op = InOperator('certname') >>> ex = ExtractOperator() >>> ex.add_field('certname') >>> fr = FromOperator('fact_contents') >>> nd = AndOperator() >>> nd.add(EqualsOperator("path", ["networking", "eth0", "macaddresses", 0])) >>> nd.add(EqualsOperator("value", "aa:bb:cc:dd:ee:00")) >>> ex.add_query(nd) >>> fr.add_query(ex) >>> op.add_query(fr) >>> print(op) ["in","certname",["from","fact_contents",["extract",["certname"],["and",["=", "path", ['networking', 'eth0', 'macaddresses', 0]],["=", "value", "aa:bb:cc:dd:ee:00"]]]]] ``` -------------------------------- ### Query resources by type and title Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Fetch resources of a specific type, optionally filtering by title. You can also paginate results using limit and offset. ```python from pypuppetdb import connect from pypuppetdb.QueryBuilder import EqualsOperator db = connect() # All File resources across the infrastructure for res in db.resources("file"): print(res) # "File[/etc/ntp.conf]" print(res.node) # certname print(res.parameters) # {"owner": "root", "mode": "0644", ...} print(res.exported) # True / False print(res.sourcefile, res.sourceline) # Specific resource by type + title for res in db.resources("service", "ntp"): print(res.node, res.tags) # Resources matching a query (nested module type) for res in db.resources( type_="sysctl::value", query=EqualsOperator("environment", "production"), ): print(res) # "Sysctl::Value[net.ipv4.ip_forward]" # Paginate large result sets for res in db.resources("package", limit=100, offset=0): print(res.name) ``` -------------------------------- ### Configure pypuppetdb for SSL/TLS Connection Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/connecting.md Connects to PuppetDB using SSL/TLS with client certificates. Requires specifying paths to the private key, public certificate, and CA root certificate, along with the host and port. ```python db = connect(ssl_key='/path/to/private.pem', ssl_cert='/path/to/public.pem', ssl_verify='/path/to/ca_crt.pem', host='puppetdb.example.com', port=8081) ``` -------------------------------- ### Generate SSL Keypair for PuppetDB Connection Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/connecting.md Command to generate a service name for SSL/TLS authentication with PuppetDB. This is a prerequisite for configuring pypuppetdb for secure connections. ```bash $ puppet cert generate ``` -------------------------------- ### db.status() / db.server_time() / db.current_version() Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Retrieve server metadata. These lightweight endpoints allow checking PuppetDB health, server clock time, and the current PuppetDB version. ```APIDOC ## `db.status()` / `db.server_time()` / `db.current_version()` — Server metadata Lightweight endpoints to check PuppetDB health, server clock, and version. ```python from pypuppetdb import connect db = connect() # PuppetDB service status status = db.status() print(status["state"]) print(status["status"]["version"]) # Server-side clock (ISO-8601 string) ts = db.server_time() print(ts) # "2024-06-01T12:00:00.123Z" # PuppetDB server version string ver = db.current_version() print(ver) # "7.14.0" ``` ``` -------------------------------- ### connect() with metric API version Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Establish a connection to PuppetDB with an explicit metric API version specified. ```APIDOC # Connect with explicit metric API version db_v1 = connect(metric_api_version="v1") print(db_v1.metric("puppetlabs.puppetdb.population:name=num-nodes")) ``` -------------------------------- ### Run Tests and Linters Source: https://github.com/voxpupuli/pypuppetdb/blob/master/CONTRIBUTING.md Executes unit tests, PEP8 and mypy checks, and security linting. This ensures code quality and adherence to standards. ```bash # Unit tests, with PEP8 and mypy (static typing) checks mypy --install-types --non-interactive pypuppetdb/ tests/ pytest --flake8 --strict-markers --mypy pypuppetdb tests # Security linter bandit -r pypuppetdb ``` -------------------------------- ### Connect to PuppetDB with RBAC Token Authentication Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/connecting.md Establishes a connection to PuppetDB using an RBAC token for authentication, typically for Puppet Enterprise. Automatically switches to HTTPS and requires host and port. ```python db = connect(token='tokenstring', host='puppetdb.example.com', port=8081) ``` -------------------------------- ### Connect to PuppetDB with Basic Authentication Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/connecting.md Connects to PuppetDB via HTTPS using HTTP Basic Authentication. Requires a reverse proxy for SSL termination and authentication. Specify protocol, host, port, username, and password. ```python db = connect(protocol='https', host='puppetdb.example.com', port=443, username='foo', password='bar') ``` -------------------------------- ### Query catalogs, resources, and edges Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Retrieve catalog objects for nodes, which contain resources and dependency edges. You can iterate through all resources or specific ones, and inspect relationships. ```python from pypuppetdb import connect db = connect() # Single node catalog catalog = db.catalog("web01.example.com") print(catalog.node, catalog.version, catalog.environment) # Iterate all resources in the catalog for res in catalog.get_resources(): print(res) # "Package[ntp]", "File[/etc/ntp.conf]", ... # Look up a specific resource and inspect its relationships svc = catalog.get_resource("Service", "ntp") for edge in catalog.get_edges(): print(edge.source, edge.relationship, edge.target) # "File[/etc/ntp.conf] - notifies - Service[ntp]" # Lookup relationships on a specific resource for rel in svc.relationships: print(rel) # Query all catalogs (use limit/query to avoid large payloads) from pypuppetdb.QueryBuilder import EqualsOperator for cat in db.catalogs(query=EqualsOperator("environment", "production"), limit=5): print(cat.node, cat.catalog_uuid) # Global edges endpoint for edge in db.edges(query=EqualsOperator("relationship", "notifies"), limit=20): print(edge.source, "->", edge.target, "on", edge.node) ``` -------------------------------- ### db.inventory() Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Retrieves node inventory, including all facts and trusted data, as Inventory objects. Supports filtering, pagination, and total count. ```APIDOC ## `db.inventory()` — Node inventory ### Description Alternative to querying facts individually; returns `Inventory` objects containing all facts and trusted data for each node. ### All inventory entries ```python for inv in db.inventory(): print(inv.node) print(inv.environment) print(inv.time) # datetime print(inv.facts.get("osfamily")) # "RedHat" print(inv.trusted) # {"certname": ..., "extensions": ...} ``` ### Filtered by certname regex ```python for inv in db.inventory(query=RegexOperator("certname", r"web\d+")): print(inv.node, inv.facts.get("ipaddress")) ``` ### With pagination ```python for inv in db.inventory( query=EqualsOperator("facts.osfamily", "Debian"), limit=50, offset=0, include_total=True, ): print(inv.node) print("Total:", db.total) ``` ``` -------------------------------- ### QueryBuilder: Boolean Operators Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Shows how to combine multiple conditions using boolean operators like AndOperator and NotOperator. ```python op = AndOperator() op.add(EqualsOperator("catalog_environment", "production")) op.add(EqualsOperator("facts_environment", "production")) nodes = db.nodes(query=op) for n in nodes: print(n.name) ``` ```python not_op = NotOperator() not_op.add(EqualsOperator("osfamily", "RedHat")) for fact in db.facts("osfamily", query=not_op): print(fact.node, fact.value) ``` -------------------------------- ### Connect to PuppetDB using 'with' statement Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/connecting.md Ensures all HTTP connections are closed explicitly upon completion of the enclosed block. Recommended for automatic connection management. ```python with connect() as db: # .. ``` -------------------------------- ### db.inventory(): Retrieve Node Inventory Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Fetches all facts and trusted data for each node, providing an alternative to querying facts individually. Supports filtering, pagination, and total count. ```python for inv in db.inventory(): print(inv.node) print(inv.environment) print(inv.time) # datetime print(inv.facts.get("osfamily")) # "RedHat" print(inv.trusted) # {"certname": ..., "extensions": ...} ``` ```python for inv in db.inventory(query=RegexOperator("certname", r"web\d+")): print(inv.node, inv.facts.get("ipaddress")) ``` ```python for inv in db.inventory( query=EqualsOperator("facts.osfamily", "Debian"), limit=50, offset=0, include_total=True, ): print(inv.node) print("Total:", db.total) ``` -------------------------------- ### Retrieve Server Metadata from PuppetDB Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Fetches lightweight metadata from PuppetDB, including service status, server time, and the PuppetDB version. Useful for health checks and version verification. ```python from pypuppetdb import connect db = connect() # PuppetDB service status status = db.status() print(status["state"]) print(status["status"]["version"]) # Server-side clock (ISO-8601 string) ts = db.server_time() print(ts) # PuppetDB server version string ver = db.current_version() print(ver) ``` -------------------------------- ### Build AST Query with Array Membership Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/advanced_queries.md Use InOperator with add_array to efficiently query for nodes whose certnames are present in a given list of hostnames. ```python >>> from pypuppetdb.QueryBuilder import * >>> op = InOperator('certname') >>> op.add_array(["prod1.server.net", "prod2.server.net"]) >>> print(op) ["in","certname",["array", ['prod1.server.net', 'prod2.server.net']]] ``` -------------------------------- ### Submit Commands to PuppetDB Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Posts commands to the 'pdb/cmd/v1' endpoint. Supported commands include 'deactivate node', 'replace catalog', 'replace facts', and 'store report'. Ensure the correct payload structure for each command. ```python from pypuppetdb import connect db = connect() # Deactivate a node result = db.command( "deactivate node", {"certname": "old-host.example.com"}, ) print(result) # {"uuid": "550e8400-e29b-41d4-a716-446655440000"} # Replace facts for a node result = db.command( "replace facts", { "certname": "web01.example.com", "environment": "production", "producer_timestamp": "2024-06-01T12:00:00.000Z", "producer": "puppet-server.example.com", "values": { "osfamily": "RedHat", "ipaddress": "10.0.0.1", }, }, ) print(result) ``` -------------------------------- ### QueryBuilder: InOperator with Static Array Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Demonstrates using the InOperator with a predefined array of values. ```python op = InOperator("certname") op.add_array(["prod1.example.com", "prod2.example.com"]) print(op) ``` -------------------------------- ### db.command() Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Submit commands to PuppetDB. This method posts commands to the `pdb/cmd/v1` endpoint and supports operations like 'deactivate node', 'replace catalog', 'replace facts', and 'store report'. ```APIDOC ## `db.command()` — Submit commands to PuppetDB Posts commands to the `pdb/cmd/v1` endpoint. Supported commands: `"deactivate node"`, `"replace catalog"`, `"replace facts"`, `"store report"`. ```python from pypuppetdb import connect db = connect() # Deactivate a node result = db.command( "deactivate node", {"certname": "old-host.example.com"}, ) print(result) # {"uuid": "550e8400-e29b-41d4-a716-446655440000"} # Replace facts for a node result = db.command( "replace facts", { "certname": "web01.example.com", "environment": "production", "producer_timestamp": "2024-06-01T12:00:00.000Z", "producer": "puppet-server.example.com", "values": { "osfamily": "RedHat", "ipaddress": "10.0.0.1", }, }, ) print(result) ``` ``` -------------------------------- ### PQL Query for Rich Node Types Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/advanced_queries.md Use the `pql()` method without projections to retrieve rich object types like `Node`. This is suitable for when you need to access object attributes directly. ```python >>> nodes = db.pql(""" nodes { facts { name = "operatingsystem" and value = "Debian" } } """) >>> for node in nodes: >>> print(node.name) foo.example.com bar.example.com ``` -------------------------------- ### db.metric() Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Queries PuppetDB JVM/application metrics using Jolokia v2 or legacy mbean v1. Returns raw metric values. ```APIDOC ## `db.metric()` — Query PuppetDB JVM/application metrics ### Description Queries the metrics endpoint (Jolokia v2 by default, or legacy mbean v1). Returns raw metric values. ### List all available metrics (v2) ```python all_metrics = db.metric() print(all_metrics) ``` ### Read a specific JVM metric (v2 / Jolokia) ```python heap = db.metric("java.lang:type=Memory") print(heap) # {"HeapMemoryUsage": {"used": 123456789, ...}, ...} # GC stats gc = db.metric("java.lang:name=PS MarkSweep,type=GarbageCollector") print(gc) ``` ### Legacy mbean endpoint (v1) ```python resp = db.metric( "puppetlabs.puppetdb.population:name=num-nodes", version="v1", ) print(resp) # {"Value": 42} ``` ``` -------------------------------- ### Query Catalogs Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Access Puppet compiled catalog data, including resources and their dependencies. You can retrieve a specific node's catalog or query across all catalogs. ```APIDOC ## `db.catalog()` / `db.catalogs()` / `db.edges()` — Query catalogs Returns `Catalog` objects that embed `Resource` and `Edge` objects representing the compiled dependency graph. ```python from pypuppetdb import connect db = connect() # Single node catalog catalog = db.catalog("web01.example.com") print(catalog.node, catalog.version, catalog.environment) # Iterate all resources in the catalog for res in catalog.get_resources(): print(res) # "Package[ntp]", "File[/etc/ntp.conf]", ... # Look up a specific resource and inspect its relationships svc = catalog.get_resource("Service", "ntp") for edge in catalog.get_edges(): print(edge.source, edge.relationship, edge.target) # "File[/etc/ntp.conf] - notifies - Service[ntp]" # Lookup relationships on a specific resource for rel in svc.relationships: print(rel) # Query all catalogs (use limit/query to avoid large payloads) from pypuppetdb.QueryBuilder import EqualsOperator for cat in db.catalogs(query=EqualsOperator("environment", "production"), limit=5): print(cat.node, cat.catalog_uuid) # Global edges endpoint for edge in db.edges(query=EqualsOperator("relationship", "notifies"), limit=20): print(edge.source, "->", edge.target, "on", edge.node) ``` ``` -------------------------------- ### Connect to PuppetDB with Explicit Metric API Version Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Connects to PuppetDB specifying the metric API version. Use this when you need to ensure a specific API version for metric queries. ```python from pypuppetdb import connect db_v1 = connect(metric_api_version="v1") print(db_v1.metric("puppetlabs.puppetdb.population:name=num-nodes")) ``` -------------------------------- ### QueryBuilder Operators Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Demonstrates the usage of various operators provided by the QueryBuilder for constructing PuppetDB AST queries programmatically. ```APIDOC ## QueryBuilder Operators ### Description Provides operator classes for constructing PuppetDB AST queries in an object-oriented style instead of raw JSON strings. All operators implement `__str__` / `json_data()`. ### Binary Operators ```python from pypuppetdb.QueryBuilder import EqualsOperator, RegexOperator, NullOperator, GreaterOperator print(EqualsOperator("environment", "production")) # ["=", "environment", "production"] print(RegexOperator("certname", r"web\d+\.example\.com")) # ["~", "certname", "web\\d+\\.example\\.com"] print(NullOperator("deactivated", False)) # ["null?", "deactivated", false] import datetime cutoff = datetime.datetime(2024, 1, 1) print(GreaterOperator("report_timestamp", cutoff)) # ">[", "report_timestamp", "2024-01-01 00:00:00"] ``` ### Boolean Operators ```python from pypuppetdb.QueryBuilder import AndOperator, NotOperator, EqualsOperator op = AndOperator() op.add(EqualsOperator("catalog_environment", "production")) op.add(EqualsOperator("facts_environment", "production")) # nodes = db.nodes(query=op) not_op = NotOperator() not_op.add(EqualsOperator("osfamily", "RedHat")) # for fact in db.facts("osfamily", query=not_op): # print(fact.node, fact.value) ``` ### InOperator with static array ```python from pypuppetdb.QueryBuilder import InOperator op = InOperator("certname") op.add_array(["prod1.example.com", "prod2.example.com"]) print(op) # ["in","certname",["array", ["prod1.example.com","prod2.example.com"]]] ``` ### Subquery + Extract + In ```python from pypuppetdb.QueryBuilder import InOperator, ExtractOperator, SubqueryOperator, AndOperator, EqualsOperator op = InOperator("certname") ex = ExtractOperator() ex.add_field("certname") sub = SubqueryOperator("facts") cond = AndOperator() cond.add(EqualsOperator("name", "operatingsystem")) cond.add(EqualsOperator("value", "Debian")) sub.add_query(cond) ex.add_query(sub) op.add_query(ex) print(op) # ["in","certname",["extract",["certname"],["select_facts",["and",["=","name","operatingsystem"],["=","value","Debian"]]]]] # for node in db.nodes(query=op): # print(node.name) ``` ### FromOperator (query across entities on root endpoint) ```python from pypuppetdb.QueryBuilder import InOperator, ExtractOperator, FromOperator, AndOperator, EqualsOperator op = InOperator("certname") ex = ExtractOperator() ex.add_field("certname") fr = FromOperator("fact_contents") fr.add_limit(50) fr.add_order_by([["certname", "asc"]]) cond = AndOperator() cond.add(EqualsOperator("path", ["networking", "eth0", "macaddress"])) cond.add(EqualsOperator("value", "aa:bb:cc:dd:ee:00")) ex.add_query(cond) fr.add_query(ex) op.add_query(fr) print(op) # for node in db.nodes(query=op): # print(node.name) ``` ### ExtractOperator with FunctionOperator (aggregate) ```python from pypuppetdb.QueryBuilder import ExtractOperator, FunctionOperator, EqualsOperator ex = ExtractOperator() ex.add_field(FunctionOperator("count")) ex.add_field("environment") ex.add_query(EqualsOperator("latest_report?", True)) ex.add_group_by("environment") print(ex) # ["extract",[["function","count"],"environment"],["=","latest_report?",true],["group_by","environment"]] ``` ``` -------------------------------- ### Query Resources Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Retrieve resource information from PuppetDB. You can filter by resource type, title, and construct complex queries. Supports pagination. ```APIDOC ## `db.resources()` — Query resources Returns a generator of `Resource` objects. Filter by Puppet resource `type_` and optionally by `title`. ```python from pypuppetdb import connect from pypuppetdb.QueryBuilder import EqualsOperator db = connect() # All File resources across the infrastructure for res in db.resources("file"): print(res) # "File[/etc/ntp.conf]" print(res.node) # certname print(res.parameters) # {"owner": "root", "mode": "0644", ...} print(res.exported) # True / False print(res.sourcefile, res.sourceline) # Specific resource by type + title for res in db.resources("service", "ntp"): print(res.node, res.tags) # Resources matching a query (nested module type) for res in db.resources( type_="sysctl::value", query=EqualsOperator("environment", "production"), ): print(res) # "Sysctl::Value[net.ipv4.ip_forward]" # Paginate large result sets for res in db.resources("package", limit=100, offset=0): print(res.name) ``` ``` -------------------------------- ### PQL Query for Raw Dictionaries Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/advanced_queries.md When using projections (fields/functions) in a PQL query or querying unsupported types, the result will be a list of dictionaries. This is useful for extracting specific data points. ```python >>> nodes = db.pql(""" nodes[certname] { facts { name = "operatingsystem" and value = "Debian" } } """) >>> for node in nodes: >>> print(node) {'certname': 'foo.example.com'} {'certname': 'bar.example.com'} ``` -------------------------------- ### db.metric(): Query PuppetDB Metrics Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Queries PuppetDB's metrics endpoint (Jolokia v2 or legacy mbean v1) to retrieve JVM and application metrics. Returns raw metric values. ```python all_metrics = db.metric() print(all_metrics) ``` ```python heap = db.metric("java.lang:type=Memory") print(heap) # {"HeapMemoryUsage": {"used": 123456789, ...}, ...} ``` ```python gc = db.metric("java.lang:name=PS MarkSweep,type=GarbageCollector") print(gc) ``` ```python resp = db.metric( "puppetlabs.puppetdb.population:name=num-nodes", version="v1", ) print(resp) # {"Value": 42} ``` -------------------------------- ### db.facts() / db.fact_names() - Query facts Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Retrieves fact data from PuppetDB. `facts()` returns a generator of `Fact` objects, filterable by name and value. `fact_names()` returns a list of all known fact names. ```APIDOC ## db.facts() / db.fact_names() ### Description Query facts from PuppetDB. `facts()` returns a generator of `Fact` objects. Filter by `name`, or by both `name` and `value`. `fact_names()` returns all known fact names. `factsets()` returns complete fact sets per certname. `fact_paths()` and `fact_contents()` allow querying structured facts. ### Method - `db.facts(name=None, value=None, query=None)` - `db.fact_names()` - `db.factsets(query=None)` - `db.fact_paths(query=None)` - `db.fact_contents(query=None)` ### Parameters - **name** (string) - Optional - The name of the fact to filter by. - **value** (string) - Optional - The value of the fact to filter by. - **query** (QueryBuilder object) - Optional - An AST query to filter facts, factsets, paths, or contents. ### Request Example ```python from pypuppetdb import connect from pypuppetdb.QueryBuilder import EqualsOperator, AndOperator db = connect() # All facts named "osfamily" for fact in db.facts("osfamily"): print(f"{fact.node}: {fact.value}") # Facts with a specific value for fact in db.facts("osfamily", "Debian"): print(fact.node, fact.environment) # With an AST query q = AndOperator() q.add(EqualsOperator("environment", "production")) q.add(EqualsOperator("name", "kernel")) for fact in db.facts(query=q): print(fact.node, fact.value) # All known fact names fact_names = db.fact_names() print("ipaddress" in fact_names) # Factsets for fs in db.factsets(query=EqualsOperator("certname", "web01.example.com")): print(fs) # Structured-fact paths for path in db.fact_paths(): print(path) # Structured-fact contents for content in db.fact_contents( query=EqualsOperator("path", ["networking", "eth0", "macaddress"]) ): print(content) ``` ### Response - **`db.facts()`**: Generator of `Fact` objects. - **`db.fact_names()`**: List of strings representing fact names. - **`db.factsets()`**: Generator of factset objects. - **`db.fact_paths()`**: Generator of fact path objects. - **`db.fact_contents()`**: Generator of fact content objects. ### Fact Object Attributes - **node** (string) - **name** (string) - **value** (string) - **environment** (string) ``` -------------------------------- ### Build a Query with QueryBuilder Source: https://github.com/voxpupuli/pypuppetdb/blob/master/docs/developer.md Use the QueryBuilder to construct complex queries in an object-oriented fashion, avoiding string concatenation. The resulting operator object can be directly passed to PuppetDB calls. ```python from pypuppetdb.QueryBuilder import * op = AndOperator() op.add(EqualOperator("facts_environment", "production")) op.add(EqualOperator("catalog_environment", "production")) ``` ```python pypuppetdb.nodes(query=op) ``` -------------------------------- ### QueryBuilder: FromOperator for Cross-Entity Queries Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Utilizes FromOperator to query across different entities, combined with ExtractOperator and other conditions. ```python op = InOperator("certname") ex = ExtractOperator() ex.add_field("certname") fr = FromOperator("fact_contents") fr.add_limit(50) fr.add_order_by([["certname", "asc"]]) cond = AndOperator() cond.add(EqualsOperator("path", ["networking", "eth0", "macaddress"])) cond.add(EqualsOperator("value", "aa:bb:cc:dd:ee:00")) ex.add_query(cond) fr.add_query(ex) op.add_query(fr) print(op) for node in db.nodes(query=op): print(node.name) ``` -------------------------------- ### Query Reports and Events Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Fetch report and event data from PuppetDB. Reports can be filtered and ordered, and their associated events can be iterated. Direct event querying and aggregation are also supported. ```APIDOC ## `db.reports()` / `db.events()` — Query reports and events `reports()` returns a generator of `Report` objects; each `Report` can itself query for its `Event` objects. ```python from pypuppetdb import connect from pypuppetdb.QueryBuilder import EqualsOperator, AndOperator, GreaterOperator import datetime db = connect() # Recent reports for a specific node, ordered newest-first import json order = json.dumps([{"field": "end_time", "order": "desc"}]) for report in db.reports( query=EqualsOperator("certname", "web01.example.com"), limit=10, order_by=order, ): print(report.hash_, report.status) # "abc123... changed" print(report.start, report.end) # datetime objects print(report.run_time) # timedelta print(report.agent_version, report.environment) # Iterate events within this report for event in report.events(): print(event) # "File[/etc/ntp.conf]/abc123..." print(event.status, event.failed) # "success", False print(event.item["old"], "->", event.item["new"]) # Query events directly with a filter for event in db.events( query=EqualsOperator("certname", "web01.example.com"), limit=50, ): print(event.node, event.item["type"], event.item["title"]) # Event counts summarized by certname counts = db.event_counts(summarize_by="certname", query=EqualsOperator("latest_report?", True)) for c in counts: print(c) # Aggregate event counts across the infrastructure agg = db.aggregate_event_counts(summarize_by="certname") print(agg) # {"successes": 42, "failures": 3, "noops": 1, "skips": 0} ``` ``` -------------------------------- ### QueryBuilder: Subquery, Extract, and In Operators Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Combines SubqueryOperator, ExtractOperator, and InOperator to build complex queries, such as finding nodes with specific fact values. ```python op = InOperator("certname") ex = ExtractOperator() ex.add_field("certname") sub = SubqueryOperator("facts") cond = AndOperator() cond.add(EqualsOperator("name", "operatingsystem")) cond.add(EqualsOperator("value", "Debian")) sub.add_query(cond) ex.add_query(sub) op.add_query(ex) print(op) for node in db.nodes(query=op): print(node.name) ``` -------------------------------- ### QueryBuilder: ExtractOperator with FunctionOperator for Aggregation Source: https://context7.com/voxpupuli/pypuppetdb/llms.txt Demonstrates using ExtractOperator with FunctionOperator to perform aggregate queries, such as counting items grouped by a field. ```python ex = ExtractOperator() ex.add_field(FunctionOperator("count")) ex.add_field("environment") ex.add_query(EqualsOperator("latest_report?", True)) ex.add_group_by("environment") print(ex) ```