Skip to main content

Juju-doctor is a pypi package which helps validate Juju deployments using probes.

Project description

🩺 juju-doctor 🩺

PyPI Release

Run a configurable set of probes (assertions) against Juju deployment artifacts, which are the output of other tools like juju, sosreport, and kubectl. To enforce best practices, these probes are organized into a ruleset, which acts as a guide for correct deployment configurations.

Usage

Here's some typical usage examples:

 juju-doctor check --help # displays the help

You can run juju-doctor against a solution archive:

∮ juju-doctor check \
    --probe file://tests/resources/probes/python/failing.py \
    --probe file://tests/resources/probes/python/passing.py \
    --status=status.yaml \
    --bundle=bundle.yaml

If you have a live deplyoment, you can also run juju-doctor against that:

∮ juju-doctor check \
    --probe file://tests/resources/probes/python/failing.py \
    --probe file://tests/resources/probes/python/passing.py \
    --model model-one \
    --model model-two

In either case, the output will look like so (configurable with --format and --verbose):

Results
├── 🔴 tests_resources_probes_python_failing.py
└── 🟢 tests_resources_probes_python_passing.py

Total: 🟢 3/6 🔴 3/6

The path to a probe can also be a URL:

# Run a remote probe against a live model juju-doctor check --model cos --probe github://canonical/grafana-k8s-operator//probes/some_probe.py

Writing Probes

Scriptlet

Scriptlet probes are written in Python, and run on standardized artifacts that can be provided either as static files, or gathered from a live model.

Currently, we support the following artifacts:

  • status: juju status --format=yaml
  • bundle: juju export-bundle
  • show_unit: juju show-unit --format=yaml

To write a probe, you should start by choosing an artifact. Your code will only have access to one artifact type at a time, but the input information can span multiple models.

Then, write a function named after your artifact (e.g., status, bundle, etc.) that takes one Dict argument: the artifact of choice indexed by model name. The function should raise an exception if you want your probe to fail, explaining why it failed.

Let's look at an example.

from typing import Dict

def status(juju_statuses: Dict[str, Dict]): # {'cos': juju_status_dict, ...}
    ... # do things with the Juju statuses
    if not all_good:
        raise Exception("'coconut' charm shouldn't be there!")

def bundle(juju_bundles: Dict[str, Dict]):
    ... # do things with the Juju bundles
    if not passing:
      raise Exception("who deployed the 'coconut' charm?")

def _first_check(...):
    ...

def _second_check(...):
    ...

# You can split multiple checks in functions
def show_unit(juju_show_units):
    ...
    _first_check()
    _second_check()

Remember: juju-doctor will only run functions that exactly match a supported artifact name, and will always pass to them a dictionary of model name mapped to the proper artifact.

For some real-world examples, check out the examples directory and this Grafana charm probe.

Ruleset

Ruleset probes are written in YAML, specifying which probes should be coordinated for a deployment validation.

Currently, the following probe types are supported:

  • scriptlet: A Python probe
  • ruleset: A declarative deployment RuleSet
  • builtin/*: A builtin plugin of a type defined in the supported plugins

Run juju-doctor schema to output the schema of a RuleSet YAML file and check out this RuleSet probe as an extensive example.

Builtins

See this doc for contributing a builtin and general information about the builtin plugin design.

Development

git clone https://github.com/canonical/juju-doctor.git
uv sync --extra=dev && source .venv/bin/activate
uv pip install -e .
juju-doctor check --help

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

juju_doctor-0.1.8.tar.gz (208.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

juju_doctor-0.1.8-py3-none-any.whl (31.4 kB view details)

Uploaded Python 3

File details

Details for the file juju_doctor-0.1.8.tar.gz.

File metadata

  • Download URL: juju_doctor-0.1.8.tar.gz
  • Upload date:
  • Size: 208.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for juju_doctor-0.1.8.tar.gz
Algorithm Hash digest
SHA256 0c6396a432ac51a41555a9e0243a057d0c0a853512f783752074634a9313cf6d
MD5 46b23dfa3d15344a9973ecb96e3ef93a
BLAKE2b-256 6762e8ed816f44aabf3a3eb25e1cb4e37af84a8856000a7a519ddd06a0f27787

See more details on using hashes here.

Provenance

The following attestation bundles were made for juju_doctor-0.1.8.tar.gz:

Publisher: release.yaml on canonical/juju-doctor

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file juju_doctor-0.1.8-py3-none-any.whl.

File metadata

  • Download URL: juju_doctor-0.1.8-py3-none-any.whl
  • Upload date:
  • Size: 31.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for juju_doctor-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 161b8be0cae5639560e5c9a74aad2c4100bb0f4fc16f5158b31d316900c646eb
MD5 bc34d73a823da12a3291f10cc0bdc271
BLAKE2b-256 7878379e290aec8e35edeebdbc2d1fd3653c7cc1c2a9b48d5193e273e5539cf8

See more details on using hashes here.

Provenance

The following attestation bundles were made for juju_doctor-0.1.8-py3-none-any.whl:

Publisher: release.yaml on canonical/juju-doctor

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page