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
13 changes: 13 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Build example container

on:
push:
pull_request:

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Docker image
run: docker build -t kuberhealthy-js-check .
22 changes: 22 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Publish package

on:
release:
types: [published]

jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
registry-url: https://npm.pkg.github.com
- run: npm publish
working-directory: client
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
FROM node:20-alpine
WORKDIR /app
COPY package.json ./
COPY client ./client
RUN npm install --production
COPY check.js ./
CMD ["node", "check.js"]
32 changes: 28 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
# JavaScript Kuberhealthy Client

This directory contains an example external check for [Kuberhealthy](https://github.com/kuberhealthy/kuberhealthy) written in JavaScript. The script demonstrates how to report a successful run or a failure back to Kuberhealthy using environment variables provided to every checker pod.
This repository contains a small client library and example external check for [Kuberhealthy](https://github.com/kuberhealthy/kuberhealthy).

## Usage
The reusable client lives in the `client/` directory and is published as `@kuberhealthy/client`. It can be imported into your own Node.js applications to report check results back to Kuberhealthy. An example checker using the client is provided in `check.js`.

1. **Add your logic**: edit `check.js` and replace the placeholder section in `main` with your own check logic. Call `report(true, [])` when the check succeeds or `report(false, ["message"])` on failure.
## Client Library

The package is published to the GitHub Packages npm registry under `@kuberhealthy/client`.

Install it by configuring npm to use the GitHub Packages registry for the `@kuberhealthy` scope:

```bash
echo "@kuberhealthy:registry=https://npm.pkg.github.com" >> ~/.npmrc
npm install @kuberhealthy/client
```

Use the client in your code:

```javascript
const { KuberhealthyClient } = require('@kuberhealthy/client');

const client = new KuberhealthyClient(process.env.KH_REPORTING_URL, process.env.KH_RUN_UUID);
await client.report(true, []);
```

Node.js 18 or newer is required for the built in `fetch` API used by the client.

## Example Checker

1. **Add your logic**: edit `check.js` and replace the placeholder section in `main` with your own check logic. Call `client.report(true, [])` when the check succeeds or `client.report(false, ["message"])` on failure.
2. **Build the image**: run `make build IMAGE=my-registry/my-check:tag` to build a container image containing your check.
3. **Push the image**: `make push IMAGE=my-registry/my-check:tag`.
4. **Create a KuberhealthyCheck**: write a khcheck resource that references your image and apply it to clusters where Kuberhealthy runs.
Expand All @@ -14,7 +38,7 @@ The check relies on two environment variables set automatically by Kuberhealthy:
- `KH_REPORTING_URL` – the endpoint where status reports are posted.
- `KH_RUN_UUID` – the UUID for this check run. It must be sent back in the `kh-run-uuid` header.

## Example khcheck
### Example khcheck

```yaml
apiVersion: kuberhealthy.github.io/v2
Expand Down
27 changes: 5 additions & 22 deletions check.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const { KuberhealthyClient } = require('@kuberhealthy/client');

const reportingURL = process.env.KH_REPORTING_URL;
const runUUID = process.env.KH_RUN_UUID;

Expand All @@ -6,34 +8,17 @@ if (!reportingURL || !runUUID) {
process.exit(1);
}

// report sends a result to Kuberhealthy
async function report(ok, errors) {
const res = await fetch(reportingURL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'kh-run-uuid': runUUID,
},
body: JSON.stringify({ ok, errors }),
});

if (res.ok) {
return;
}

const text = await res.text();
throw new Error(`Kuberhealthy responded with ${res.status}: ${text}`);
}
const client = new KuberhealthyClient(reportingURL, runUUID);

async function main() {
try {
// Add your check logic here.
await report(true, []);
await client.report(true, []);
console.log('Reported success to Kuberhealthy');
} catch (err) {
console.error('Check logic failed:', err);
try {
await report(false, [err.message]);
await client.report(false, [err.message]);
} catch (e) {
console.error('Failed to report failure:', e);
}
Expand All @@ -42,5 +27,3 @@ async function main() {
}

main();

module.exports = { report };
27 changes: 27 additions & 0 deletions client/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class KuberhealthyClient {
constructor(reportingURL, runUUID) {
if (!reportingURL || !runUUID) {
throw new Error('reportingURL and runUUID are required');
}
this.reportingURL = reportingURL;
this.runUUID = runUUID;
}

async report(ok, errors) {
const res = await fetch(this.reportingURL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'kh-run-uuid': this.runUUID,
},
body: JSON.stringify({ ok, errors }),
});

if (!res.ok) {
const text = await res.text();
throw new Error(`Kuberhealthy responded with ${res.status}: ${text}`);
}
}
}

module.exports = { KuberhealthyClient };
13 changes: 13 additions & 0 deletions client/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "@kuberhealthy/client",
"version": "0.1.0",
"description": "Node.js client for Kuberhealthy",
"main": "index.js",
"files": ["index.js"],
"publishConfig": {
"registry": "https://npm.pkg.github.com"
},
"engines": {
"node": ">=18"
}
}
12 changes: 9 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
{
"name": "kuberhealthy-javascript-client",
"name": "kuberhealthy-check-example",
"version": "0.1.0",
"description": "Example Kuberhealthy external check written in JavaScript",
"private": true,
"description": "Example external check for Kuberhealthy using the JavaScript client",
"main": "check.js",
"scripts": {
"start": "node check.js"
},
"dependencies": {}
"engines": {
"node": ">=18"
},
"dependencies": {
"@kuberhealthy/client": "file:./client"
}
}