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.9.tar.gz (222.5 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.9-py3-none-any.whl (31.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: juju_doctor-0.1.9.tar.gz
  • Upload date:
  • Size: 222.5 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.9.tar.gz
Algorithm Hash digest
SHA256 2f6db93e87c54b95e3a30549826b9c169774a4d20a7e816abc7248c6c66f8600
MD5 92ed281b975b7c5620668738267583f1
BLAKE2b-256 3f91949df6cde1abae9b4a41ab23be798a5182e527c11ee22459adf2c13441f4

See more details on using hashes here.

Provenance

The following attestation bundles were made for juju_doctor-0.1.9.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.9-py3-none-any.whl.

File metadata

  • Download URL: juju_doctor-0.1.9-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.9-py3-none-any.whl
Algorithm Hash digest
SHA256 35a7fd2be466156c03e181a613eaa89c23017838f1e1d69951e79163e3dc4b62
MD5 6574a4d64d931869d9538ab59b311b1d
BLAKE2b-256 df6bce502e5a4336bbb851c3435efd090715a4baf874899be8af06892d5dc600

See more details on using hashes here.

Provenance

The following attestation bundles were made for juju_doctor-0.1.9-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