bzm-opl-gen
Generate — and live-test — BlazeMeter OPL (On-Premise/Private Location) Kubernetes & OpenShift deployments for customers, driven by facts from their actual BlazeMeter account instead of hand-edited templates.
BlazeMeter API customer parameters
(harbor, ships, funcIds, (namespace, registry, platform,
live image inventory) functionality, secret policy, ...)
\ /
v v
facts.json ----> bzm-opl-gen generate ----> out/*.yaml + README
|
bzm-opl-gen livetest
(apply to a cluster, or compose up
a docker bundle on this host, and
poll the API until agent is ONLINE)
Why account facts matter. funcIds: ["performance"] tells the generator that
browser and mock-service images are dead weight, so they never ship. The
location's own image list gives exact versions and the right IMAGE_OVERRIDES
keys for a private registry — the engine is blazemeter/v4 tagged
taurus-cloud, which is easy to get wrong by hand.
Install
Needs Python 3.10+ and nothing else — the UI ships prebuilt, so there is no npm step.
pipx install "bzm-opl-gen[ui]"
bzm-opl-gen ui # opens the web UI
uv tool install works the same. Upgrade with pipx upgrade bzm-opl-gen, pin
with "bzm-opl-gen[ui]==0.4.1".
[ui] is the web page, [mcp] the MCP server (docs/mcp.md),
[ui,mcp] both. The bare CLI pulls in one package, cryptography — it reads
the certificate a docker agent serves its virtual services with, to check the
hostname against it.
Installing from git, or from a release wheel
To track main, or to run a tag PyPI has not seen:
pipx install "bzm-opl-gen[ui] @ git+https://github.com/benjithompson/bzm-opl-generator@v0.4.1"
Drop @v0.4.1 to track main; add --force to reinstall over an existing copy.
Every release also attaches the built wheel. Download it from the Releases page,
or with gh release download --repo benjithompson/bzm-opl-generator, then
install the file by its real name:
pipx install './bzm_opl_gen-0.4.1-py3-none-any.whl[ui]'
Name the version rather than globbing it. Neither the shell (inside quotes) nor
pipx expands a * there, and the error is Unable to parse package spec.
From a checkout
Working on it, or already cloned? Same page, no wheel:
python3 -m venv .venv && .venv/bin/pip install -e ".[ui]"
.venv/bin/bzm-opl-gen ui
[dev] instead of [ui] adds the test dependencies — see
Contributing.
Credentials
Everything that talks to BlazeMeter takes --api-key path/to/api-key.json — an
API key (Settings → API Keys) as { "id": "...", "secret": "..." }:
cp examples/api-key.example.json api-key.json # then fill in id + secret
api-key*.json is gitignored. Read access is enough except where something is
created or changed: create-location, create-agent, delete-location,
livetest, and generate --rotate-token, which mints a credential and kills
the previous one.
Quick start
bzm-opl-gen ui walks the whole thing in a browser. The CLI equivalent:
# 0. before any of it exists: how much cluster does the load target need?
bzm-opl-gen plan --users 5000 -o ./plan # writes capacity-request.md
# 1. find (or create) the location and agent
bzm-opl-gen locations --api-key api-key.json --account-name "<ACCOUNT NAME>"
bzm-opl-gen create-agent --api-key api-key.json --harbor-id <harbor-id> \
--name my-k8s-agent # prints ship_id + AUTH_TOKEN -- keep the token
# 2. gather the location's facts from the account
bzm-opl-gen facts --api-key api-key.json --harbor-id <harbor-id>
# 3. generate manifests. The token comes from you, not from the API: generate
# never mints one, because minting revokes the token a running agent holds
bzm-opl-gen generate --namespace my-project --auth-token <token> -o out/
# 4. preflight the target cluster before anyone waits on a stuck run
bzm-opl-gen doctor --facts facts.json --manifests out/ -n my-project
# 5. deploy
kubectl apply -n my-project -f out/
Step 0 needs no account and no cluster — that is the case it exists for, since its answer is what you raise the cluster request with (docs/capacity-planning.md).
out/README.md is written for whoever receives the bundle; out/profile.json
is the resolved options minus the token, replayed with generate --profile.
Also: --format helm for a chart (docs/helm.md),
--format docker for one agent as one container
(docs/docker.md), --private-registry plus images --pull --mirror for an air-gapped cluster, and livetest to start a bundle for real
and wait for the agent to come online -- a cluster for the manifests, docker compose on this host for a docker bundle
(docs/live-test.md).
Re-generating against a live agent is safe.
generatenever mints an AUTH_TOKEN as a side effect — it takes--auth-token, reads back the token already in-o, or leaves the placeholder. Only--rotate-tokenmints, and it warns first: the endpoint invalidates the previous token, so the whole bundle has to be re-applied or that agent sits at0/1 Running(docs/options.md).
Without a BlazeMeter account
Three paths need no account, and plan above needs no cluster. The sample facts
file gets you to real manifests — edit it and watch which images land in
IMAGE_OVERRIDES:
bzm-opl-gen generate --facts examples/facts.example.json --namespace demo -o out/
For a customer whose account you cannot reach, the three values BlazeMeter shows on an agent render every manifest (in the web UI, step 1 → Enter values manually):
bzm-opl-gen facts --manual --harbor-id <harbor-id> --ship-id <ship-id> \
--func-ids performance
bzm-opl-gen generate --auth-token <token> --namespace their-ns -o out/
Nothing is validated and nothing is sent to BlazeMeter. What you give up: the
crane tag floats on latest, IMAGE_OVERRIDES comes from the built-in catalogue
rather than the location — complete except for GUI browser images, where the
account names one of 60+ pinned repos and nothing here can guess which — and
doctor has no concurrency numbers. With a key none of that applies, and it
needs no deployed agent: facts reads the location's own image list.
The cluster has the same answer — someone with access runs the read-only scripts/bzm-cluster-evidence.sh, and you preflight from the file:
./scripts/bzm-cluster-evidence.sh -n their-ns > cluster-evidence.json
bzm-opl-gen doctor --facts facts.json --cluster-evidence cluster-evidence.json
bzm-opl-gen suggest --cluster-evidence cluster-evidence.json
suggest answers what comes first: what that cluster implies about the options
to generate with, each suggestion naming its evidence and whether it settles the
option or only narrows it
(docs/preflight.md).
Documentation
| docs/capacity-planning.md | plan — sizing a cluster, and the request document to ask for it with |
| docs/options.md | every generate option and profile key |
| docs/web-ui.md | bzm-opl-gen ui — the two views, each step, why it binds locally |
| docs/mcp.md | the MCP server, for an AI session with no checkout |
| docs/helm.md | --format helm, and helm upgrade |
| docs/docker.md | --format docker, and which options reach it |
| docs/service-virtualization.md | ingress backends for mockServices, and sv-expose |
| docs/preflight.md | doctor, suggest, toolcheck, engine sizing |
| docs/live-test.md | the live rig: registry, proxy + CA, egress containment |
| docs/hardened-engines.md | the security context crane stamps on the pods it spawns |
| docs/crane-nginx-ingress-port.md | write-up of crane's nginx Ingress port defect |
| scripts/bzm-cluster-evidence.sh | read-only script a customer runs, feeding --cluster-evidence |
| CONTEXT.md | the glossary — functionality, funcId, slot, bundle, sizing, agent |
| CONTRIBUTING.md | setup, test layers, PR flow, cutting a release |
Contributing
python3 -m venv .venv && .venv/bin/pip install -e ".[dev]"
.venv/bin/pytest tests -q # ~3s, no cluster, must end "N passed"
You need no BlazeMeter account to work on the generator — examples/facts.example.json
drives it. Everything lands on main through a PR. Full guide in
CONTRIBUTING.md, and CONTEXT.md is the glossary
to read before naming anything new.
Support
Bugs and feature requests go to Issues. Please don't report a security problem there — a private-location AUTH_TOKEN is a credential, so use a security advisory instead, which stays private until it is published.
This is an independent project, not a BlazeMeter product: it generates manifests for BlazeMeter private locations but carries no BlazeMeter support commitment. For the platform itself — the agent, crane, the API — go to BlazeMeter support.
License
Apache-2.0. See NOTICE for attribution; container images the generated manifests reference are published by BlazeMeter under their own terms and are not redistributed here.
Not yet covered
- SV expose backends beyond the four implemented, and crane's nginx Ingress
under controllers other than
ingress-nginxandingress-to-route - External Secrets Operator / CSI secret-store variants
- Multi-engine runs (the rig validates one engine pod, on one node)
- Engine ephemeral-storage sizing under a real 40GB
/tmpworkload
References: help.blazemeter.com — private locations, agent env variables, system requirements, Blazemeter/helm-crane.
Metadata
Release files for bzm-opl-gen 0.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| bzm_opl_gen-0.4.1.tar.gz | 797.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bzm_opl_gen-0.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.4 MB
Release files / bzm_opl_gen-0.4.1.tar.gz
| Download URL | bzm_opl_gen-0.4.1.tar.gz |
|---|---|
| Size | 797.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4c8d0fa1a97cc07df8a6d5e122fc4089a608d21fa2e714b3a9089139793aeea6
|
|
BLAKE2b-256 checksum How to use checksums |
984d252fd9367073507ff89de0a452465b975db73a1c2bc2fd08e53d40676138
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 9, 2026.
Transparency logRelease files / bzm_opl_gen-0.4.1-py3-none-any.whl
| Download URL | bzm_opl_gen-0.4.1-py3-none-any.whl |
|---|---|
| Size | 576.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
60edf3067afd940e9dc4963773a3bb76f7d1359c8d3448877d2fe3dbe7322295
|
|
BLAKE2b-256 checksum How to use checksums |
fc8a8c6402342a7b5dd5b7ddd89f38a7c2c556e1f178fcdeaa051b9e2067cf9c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 9, 2026.
Transparency log