Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Build

on:
push:
pull_request:

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.x"
- name: Build package
run: |
python -m pip install --upgrade pip
pip install build
python -m build
- name: Build example container
run: |
make build IMG=kuberhealthy-client:test
28 changes: 28 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Publish

on:
release:
types: [published]

jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.x"
- name: Build package
run: |
python -m pip install --upgrade pip
pip install build
python -m build
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
- name: Attach artifacts to release
uses: softprops/action-gh-release@v1
with:
files: dist/*
5 changes: 3 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
FROM python:3.11-alpine

WORKDIR /app
COPY client.py .
COPY kuberhealthy_client kuberhealthy_client
COPY example example

CMD ["python3", "/app/client.py"]
CMD ["python3", "/app/example/client.py"]
35 changes: 25 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
# Python Kuberhealthy Client

This directory contains a minimal Python application that demonstrates how to
report status back to [Kuberhealthy](https://github.com/kuberhealthy/kuberhealthy).
The example loads the `KH_REPORTING_URL` and `KH_RUN_UUID` environment variables
provided to checker pods and includes commented calls to `report_ok` and
`report_error`.
This repository provides a small Python library for reporting check results back to [Kuberhealthy](https://github.com/kuberhealthy/kuberhealthy). It also includes a runnable example program and container configuration.

## Installing

Install the client into your own project:

```bash
pip install kuberhealthy-client
```

The library exposes two helpers:

```python
from kuberhealthy_client import report_ok, report_error

# Environment variables KH_REPORTING_URL and KH_RUN_UUID are read automatically.
report_ok()
report_error("something went wrong")
```

Both functions accept optional `url` and `run_uuid` keyword arguments if you prefer to supply values directly.

## Running the example

Set the `KH_REPORTING_URL` and `KH_RUN_UUID` environment variables, add your
check logic to `client.py`, and then run:
check logic to `example/client.py`, and then run:

```bash
python3 client.py
python3 example/client.py
```

Within the `main` function, uncomment either `report_ok()` or
Expand All @@ -30,9 +46,8 @@ make push IMG=myrepo/example-check:latest

## Using in your own checks

1. Add your check logic to `client.py` by replacing the placeholder in `main`.
Call `report_ok()` when the check succeeds or `report_error("message")`
when it fails.
1. Add your check logic to `example/client.py` or your own script. Call `report_ok()`
when the check succeeds or `report_error("message")` when it fails.
2. Build and push your image as shown above.
3. Create a `KuberhealthyCheck` resource pointing at your image and apply it to any
cluster where Kuberhealthy runs:
Expand Down
16 changes: 16 additions & 0 deletions example/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env python3
"""Example Kuberhealthy client using the :mod:`kuberhealthy_client` package."""

from kuberhealthy_client import report_ok, report_error


def main() -> None:
"""Run the example client."""
# INSERT YOUR CHECK LOGIC HERE
# report_ok()
# report_error("something went wrong")
pass


if __name__ == "__main__":
main()
37 changes: 12 additions & 25 deletions client.py → kuberhealthy_client/__init__.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
#!/usr/bin/env python3
"""Example Kuberhealthy client in Python."""
"""Lightweight client for reporting check results to Kuberhealthy."""

from __future__ import annotations

import json
import os
import urllib.request

from typing import Optional

KH_REPORTING_URL = "KH_REPORTING_URL"
KH_RUN_UUID = "KH_RUN_UUID"


def _get_env(name: str) -> str:
"""Return the value of the environment variable *name* or raise an error."""
value = os.getenv(name)
if not value:
raise EnvironmentError(f"{name} must be set")
return value


def _post_status(payload: dict) -> None:
def _post_status(payload: dict, *, url: Optional[str] = None, run_uuid: Optional[str] = None) -> None:
"""Send *payload* to the Kuberhealthy reporting URL."""
url = _get_env(KH_REPORTING_URL)
run_uuid = _get_env(KH_RUN_UUID)
url = url or _get_env(KH_REPORTING_URL)
run_uuid = run_uuid or _get_env(KH_RUN_UUID)
data = json.dumps(payload).encode("utf-8")
request = urllib.request.Request(
url,
Expand All @@ -31,24 +30,12 @@ def _post_status(payload: dict) -> None:
with urllib.request.urlopen(request, timeout=10) as response: # nosec B310
response.read()


def report_ok() -> None:
def report_ok(*, url: Optional[str] = None, run_uuid: Optional[str] = None) -> None:
"""Report a successful check to Kuberhealthy."""
_post_status({"OK": True, "Errors": []})
_post_status({"OK": True, "Errors": []}, url=url, run_uuid=run_uuid)


def report_error(message: str) -> None:
def report_error(message: str, *, url: Optional[str] = None, run_uuid: Optional[str] = None) -> None:
"""Report a failure to Kuberhealthy with *message* as the error."""
_post_status({"OK": False, "Errors": [message]})


def main() -> None:
"""Run the example client."""
# INSERT YOUR CHECK LOGIC HERE
# report_ok()
# report_error("something went wrong")
pass

_post_status({"OK": False, "Errors": [message]}, url=url, run_uuid=run_uuid)

if __name__ == "__main__":
main()
__all__ = ["report_ok", "report_error", "KH_REPORTING_URL", "KH_RUN_UUID"]
16 changes: 16 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"

[project]
name = "kuberhealthy-client"
version = "0.1.0"
description = "Python client for reporting check results to Kuberhealthy"
readme = "README.md"
authors = [{name = "Kuberhealthy"}]
license = {text = "Apache-2.0"}
requires-python = ">=3.8"

[tool.setuptools.packages.find]
where = ["."]
include = ["kuberhealthy_client"]