Migrate BMS skill to Python-only CLI with audit logging
This commit is contained in:
197
README.md
197
README.md
@@ -1,15 +1,6 @@
|
||||
# openclaw-bms
|
||||
|
||||
Python rewrite of the OpenClaw Kaseya BMS skill for ticket and note workflows.
|
||||
|
||||
## Goals
|
||||
|
||||
- reliable ticket CRUD
|
||||
- reliable ticket note CRUD
|
||||
- correct account/location relationship handling
|
||||
- cache stable CRM lookups
|
||||
- support template-based ticket creation cleanly
|
||||
- keep a small shell compatibility layer for existing `scripts/*.sh` entrypoints
|
||||
Python-first OpenClaw skill for Kaseya BMS ticket and note workflows.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -17,10 +8,16 @@ Python rewrite of the OpenClaw Kaseya BMS skill for ticket and note workflows.
|
||||
python3 -m pip install -e .
|
||||
```
|
||||
|
||||
Or run directly from the repo:
|
||||
Primary usage:
|
||||
|
||||
```bash
|
||||
bash scripts/bms.sh --help
|
||||
bms --help
|
||||
```
|
||||
|
||||
Alternative direct module invocation:
|
||||
|
||||
```bash
|
||||
python3 -m openclaw_bms --help
|
||||
```
|
||||
|
||||
## Configuration
|
||||
@@ -29,39 +26,35 @@ bash scripts/bms.sh --help
|
||||
export BMS_TENANT="your-tenant"
|
||||
export BMS_USERNAME="your-user"
|
||||
export BMS_PASSWORD="your-password"
|
||||
export BMS_MFA_CODE="123456" # when needed
|
||||
export BMS_MFA_CODE="123456" # when needed
|
||||
export BMS_API_BASE="https://api.bms.kaseya.com"
|
||||
export BMS_TOKEN_FILE="$HOME/.bms_token.json"
|
||||
export BMS_CACHE_FILE="$HOME/.cache/openclaw-bms/cache.json"
|
||||
```
|
||||
|
||||
## Key behavior
|
||||
## Core behavior
|
||||
|
||||
### Accounts and Locations
|
||||
|
||||
Locations are account-scoped.
|
||||
Locations are tied to accounts.
|
||||
|
||||
Use:
|
||||
That means a location named `Main` under one account is a different object from `Main` under another account.
|
||||
Always resolve locations in the context of an account.
|
||||
|
||||
Commands:
|
||||
|
||||
```bash
|
||||
bms accounts
|
||||
bms locations --account 12345
|
||||
```
|
||||
|
||||
Do not assume a location name like `Main` is globally unique. A location name can exist under multiple accounts with different IDs.
|
||||
|
||||
Cached for 24 hours:
|
||||
- accounts list
|
||||
- locations per account
|
||||
|
||||
Refresh explicitly:
|
||||
|
||||
```bash
|
||||
bms accounts --refresh
|
||||
bms locations --account 12345
|
||||
bms locations --account 12345 --refresh
|
||||
```
|
||||
|
||||
### Tickets
|
||||
Caching:
|
||||
- accounts cached for 24 hours
|
||||
- locations cached per account for 24 hours
|
||||
|
||||
### Ticket CRUD
|
||||
|
||||
List/search:
|
||||
|
||||
@@ -69,6 +62,12 @@ List/search:
|
||||
bms tickets list --status Open --assignee "Jane Doe"
|
||||
```
|
||||
|
||||
Get:
|
||||
|
||||
```bash
|
||||
bms tickets get 12345
|
||||
```
|
||||
|
||||
Create:
|
||||
|
||||
```bash
|
||||
@@ -85,7 +84,7 @@ bms tickets create \
|
||||
--open-date 2026-04-07T14:00:00+00:00
|
||||
```
|
||||
|
||||
Template-based create:
|
||||
Create from template:
|
||||
|
||||
```bash
|
||||
bms tickets create \
|
||||
@@ -96,65 +95,123 @@ bms tickets create \
|
||||
--queue-id 9
|
||||
```
|
||||
|
||||
Template logic:
|
||||
- fetches the template
|
||||
- merges template defaults with CLI overrides
|
||||
- CLI values win
|
||||
- validates required fields before the create call
|
||||
- requires routing via either `queue-id` or `assignee-id`
|
||||
- makes exactly one create API call per invocation
|
||||
- treats create as success only when the response includes success=true and a valid ticket ID
|
||||
Template create flow:
|
||||
- fetch template
|
||||
- merge template defaults with explicit CLI overrides
|
||||
- validate required fields before the API call
|
||||
- require either `queue-id` or `assignee-id`
|
||||
- make exactly one create API call per invocation
|
||||
- require a valid ticket ID in the response before reporting success
|
||||
|
||||
### Notes
|
||||
Patch:
|
||||
|
||||
```bash
|
||||
bms tickets patch 12345 /StatusId 6
|
||||
```
|
||||
|
||||
Assign:
|
||||
|
||||
```bash
|
||||
bms tickets assign 12345 --details "Routing to tier 2" --type-id 1 --status-id 6 --queue-id 7
|
||||
```
|
||||
|
||||
Delete:
|
||||
|
||||
```bash
|
||||
bms tickets delete 12345
|
||||
```
|
||||
|
||||
### Ticket Note CRUD
|
||||
|
||||
List notes:
|
||||
|
||||
```bash
|
||||
bms notes list 33919447
|
||||
bms notes list 12345
|
||||
```
|
||||
|
||||
Add a note with a custom date:
|
||||
Add note with custom date:
|
||||
|
||||
```bash
|
||||
bms notes add 33919447 --message "Backfilled note" --note-date 2026-04-01T15:00:00+00:00
|
||||
bms notes add 12345 --message "Backfilled note" --note-date 2026-04-01T15:00:00+00:00
|
||||
```
|
||||
|
||||
Update a note with a custom date:
|
||||
Update note with custom date:
|
||||
|
||||
```bash
|
||||
bms notes update 33919447 1001 --message "Corrected note" --note-date 2026-04-01T16:00:00+00:00
|
||||
bms notes update 12345 1001 --message "Corrected note" --note-date 2026-04-01T16:00:00+00:00
|
||||
```
|
||||
|
||||
Delete a note:
|
||||
Delete note:
|
||||
|
||||
```bash
|
||||
bms notes delete 33919447 1001
|
||||
bms notes delete 12345 1001
|
||||
```
|
||||
|
||||
## Architectural decisions
|
||||
### Lookups
|
||||
|
||||
```bash
|
||||
bms lookup statuses
|
||||
bms lookup priorities
|
||||
bms lookup types
|
||||
bms lookup sources
|
||||
```
|
||||
|
||||
Notes:
|
||||
- `types` maps to issue-type lookup in the public BMS v2 Swagger.
|
||||
- `sources` is not exposed in the public BMS v2 Swagger; the command fails explicitly and expects tenant-specific source IDs.
|
||||
|
||||
### Templates
|
||||
|
||||
```bash
|
||||
bms templates tickets list
|
||||
bms templates tickets get 7
|
||||
bms templates notes list
|
||||
bms templates timelogs list
|
||||
```
|
||||
|
||||
Templates are read-only.
|
||||
|
||||
## Audit logging
|
||||
|
||||
Write operations only are logged.
|
||||
Reads are not logged.
|
||||
|
||||
Logged operations:
|
||||
- auth login
|
||||
- auth refresh
|
||||
- ticket create
|
||||
- ticket patch
|
||||
- ticket delete
|
||||
- ticket assign
|
||||
- note add
|
||||
- note update
|
||||
- note delete
|
||||
|
||||
Log path:
|
||||
|
||||
```text
|
||||
~/.bms-actions/YYYY-MM-DD.jsonl
|
||||
```
|
||||
|
||||
Entry shape:
|
||||
- `timestamp`
|
||||
- `command`
|
||||
- `args_sanitized`
|
||||
- `result` or `error`
|
||||
- `status`
|
||||
- `revert_info` when available
|
||||
|
||||
Secrets are redacted:
|
||||
- `BMS_PASSWORD`
|
||||
- `BMS_MFA_CODE`
|
||||
- tokens
|
||||
- authorization headers
|
||||
|
||||
## Architecture
|
||||
|
||||
- Python standard library only
|
||||
- avoids packaging friction for a personal skill
|
||||
- console entry point via `pyproject.toml`
|
||||
- no shell wrappers required
|
||||
- service layer separated from CLI
|
||||
- easier to audit and extend
|
||||
- caching stored in a JSON file
|
||||
- simple, transparent, sufficient for account/location lookups
|
||||
- shell scripts kept as compatibility wrappers
|
||||
- existing command habits keep working
|
||||
|
||||
## Audit notes
|
||||
|
||||
Primary audit focus was on:
|
||||
- ticket create safety
|
||||
- note CRUD support
|
||||
- account/location correctness
|
||||
- template create correctness
|
||||
|
||||
Changes from bash version:
|
||||
- removed fragile mixed endpoint usage
|
||||
- fixed account/location handling through CRM endpoints
|
||||
- added explicit cache for accounts and per-account locations
|
||||
- added `open-date` support for ticket creation
|
||||
- added `note-date` support for note create and update
|
||||
- added full note CRUD in the Python CLI
|
||||
- reduced duplicate-create risk by validating before create and checking response semantics after create
|
||||
- file-based cache for stable CRM data
|
||||
- file-based audit log for write history and rollback context
|
||||
|
||||
Reference in New Issue
Block a user