feat(bitdefender): doc-verify assignPolicy/push + add full-API build-out tracker
- assign_policy: add inheritFromAbove option; mark VERIFIED via official docs (policyId/targetIds/forcePolicyInheritance/inheritFromAbove; not applied to ENFORCED-policy targets). - setPushEventSettings: documented serviceType (splunk/cef/jsonRPC), TLS 1.2+ receiver requirement, subscribeToEventTypes event-flag map; webhook receiver pattern noted. - api-reference.md: cite GravityZone Support Center as authoritative source. - add references/BUILDOUT.md — master checklist to implement every API method module-by-module; seeded with current done/todo/dead state. - memory: reference_gravityzone_support (+ index). selftest 42/42. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
## Reference
|
||||
- [ACG resource map](reference_resource_map.md) — **READ THIS FIRST** when a task references a server/service/tenant/API. What we have access to, how to connect from this machine, per-machine exceptions, gotchas. Points at the detail files below.
|
||||
- [GravityZone support center](reference_gravityzone_support.md) — Authoritative Bitdefender GravityZone product + Public API docs; use to confirm UNVERIFIED `bitdefender` skill methods/param shapes (push setPushEventSettings, assignPolicy, report/account writes, maintenancewindows/integrations names).
|
||||
- [GURU-5070 Rust toolchain](reference_guru5070_rust_toolchain.md) — GURU-5070 now has cargo + MSVC + protoc; build/clippy/test guru-connect LOCALLY (set PROTOC to the winget path) instead of the build host. CI only clippy-checks the Linux server, not the Windows agent.
|
||||
- [ACG Office Network Infrastructure](infra_office_network.md) — IPs/hosts/roles for pfSense/Jupiter/VMs/Docker. Check before assuming; .21 (Uranus) is storage.
|
||||
- [Power Failure Runbook](../POWER_FAILURE_RUNBOOK.md) — Recovery order after a power event: Tailscale routes, libvirt/VMs, Seafile, NPM/DNS.
|
||||
|
||||
16
.claude/memory/reference_gravityzone_support.md
Normal file
16
.claude/memory/reference_gravityzone_support.md
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
name: reference_gravityzone_support
|
||||
description: Authoritative GravityZone product + Public API documentation (Bitdefender Support Center)
|
||||
metadata:
|
||||
type: reference
|
||||
---
|
||||
|
||||
GravityZone Support Center — authoritative docs for the Bitdefender product and
|
||||
its Public JSON-RPC API (methods, params, modules):
|
||||
https://www.bitdefender.com/business/support/en/77211-79436-welcome-to-gravityzone.html
|
||||
|
||||
Use it to confirm UNVERIFIED methods/param shapes before relying on them in the
|
||||
`bitdefender` skill — e.g. `push.setPushEventSettings` nested shape,
|
||||
`network.assignPolicy` options, report/account write methods, and the correct
|
||||
`maintenancewindows`/`integrations` method names. The skill's own verified-vs-
|
||||
unverified spec lives in `.claude/skills/bitdefender/references/api-reference.md`.
|
||||
87
.claude/skills/bitdefender/references/BUILDOUT.md
Normal file
87
.claude/skills/bitdefender/references/BUILDOUT.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# Bitdefender skill — full API build-out tracker
|
||||
|
||||
Goal: implement EVERY GravityZone Public API method the docs expose (and the
|
||||
tenant license allows), one module at a time. Source of truth for method/param
|
||||
shapes: the GravityZone Support Center
|
||||
(https://www.bitdefender.com/business/support/en/77209-125277-public-api.html).
|
||||
|
||||
Legend: `[x]` wrapped + tested · `[ ]` todo · `[~]` partial/unverified ·
|
||||
`[DEAD]` in key scope but license/feature OFF on this tenant.
|
||||
|
||||
Per-module workflow: fetch module doc -> list methods + params -> add to
|
||||
`gz_client.py` + `gz.py` (gate state-changing behind `--confirm`) -> test
|
||||
(reads live; writes gated-only, never executed on prod during build) -> update
|
||||
`api-reference.md` + tick here.
|
||||
|
||||
---
|
||||
|
||||
## general / authentication
|
||||
- [x] getApiKeyDetails
|
||||
|
||||
## licensing
|
||||
- [x] getLicenseInfo
|
||||
- [ ] (enumerate: getMonthlyUsage? / others)
|
||||
|
||||
## companies
|
||||
- [x] getCompanyDetails
|
||||
- [ ] getCompaniesList / getCompanyDetailsByUser
|
||||
- [ ] createCompany / updateCompany / deleteCompany / suspend / activate (enumerate; gated)
|
||||
|
||||
## network
|
||||
- [x] getNetworkInventoryItems · getEndpointsList · getManagedEndpointDetails
|
||||
- [x] getScanTasksList · createScanTask · moveEndpoints
|
||||
- [x] createCustomGroup · deleteCustomGroup · moveCustomGroup · deleteEndpoint
|
||||
- [x] assignPolicy
|
||||
- [ ] createReconfigureClientTask (gated)
|
||||
- [ ] createUninstallTask (gated)
|
||||
- [ ] setEndpointLabel
|
||||
- [ ] (enumerate remaining: getEndpointsCounts, getManagedEndpointDetails opts, etc.)
|
||||
|
||||
## packages
|
||||
- [x] getPackagesList · createPackage · getInstallationLinks · deletePackage
|
||||
- [ ] getPackageDetails (param: packageId)
|
||||
- [ ] (enumerate remaining)
|
||||
|
||||
## policies
|
||||
- [x] getPoliciesList · getPolicyDetails (FULL config)
|
||||
- [x] assignPolicy (lives in /network)
|
||||
- [ ] (confirm no other policy methods exist)
|
||||
|
||||
## reports
|
||||
- [x] getReportsList
|
||||
- [ ] createReport (param: name, type, targetIds, ...) (gated-ish)
|
||||
- [ ] getDownloadLinks · deleteReport (enumerate)
|
||||
|
||||
## quarantine
|
||||
- [x] getQuarantineItemsList (computers)
|
||||
- [ ] createRemoveQuarantineItemTask (gated)
|
||||
- [ ] createRestoreQuarantineItemTask (gated)
|
||||
- [ ] exchange quarantine variants (enumerate)
|
||||
|
||||
## incidents / EDR
|
||||
- [x] getBlocklistItems · addToBlocklist · removeFromBlocklist
|
||||
- [x] createIsolateEndpointTask · createRestoreEndpointFromIsolationTask
|
||||
- [DEAD] getIncidentsList (Method not found on this tenant)
|
||||
- [ ] custom rules / changeIncidentStatus / updateIncidentNote (enumerate; likely EDR-license gated)
|
||||
|
||||
## push (event service)
|
||||
- [x] getPushEventSettings · getPushEventStats · setPushEventSettings
|
||||
- [ ] sendTestPushEvent (enumerate)
|
||||
|
||||
## accounts (fully enumerated from docs)
|
||||
- [x] getAccountsList
|
||||
- [x] getNotificationsSettings
|
||||
- [ ] getAccountDetails
|
||||
- [ ] createAccount (gated)
|
||||
- [ ] updateAccount (gated)
|
||||
- [ ] deleteAccount (gated)
|
||||
- [ ] configureNotificationsSettings (gated)
|
||||
|
||||
## integrations
|
||||
- [ ] (enumerate; getPSAIntegrationList was a name-miss — find correct names)
|
||||
|
||||
## maintenance windows
|
||||
- [DEAD] getMaintenanceWindows / *List → "not available" on this tenant
|
||||
|
||||
## patchmanagement / phasr
|
||||
- [DEAD] license OFF (managePatchManagement=false; phasr feature off)
|
||||
@@ -1,5 +1,10 @@
|
||||
# Bitdefender GravityZone Cloud Public API Reference
|
||||
|
||||
> **Authoritative product + API docs:** GravityZone Support Center —
|
||||
> https://www.bitdefender.com/business/support/en/77211-79436-welcome-to-gravityzone.html
|
||||
> (everything about the product and the Public API). Use it to confirm any
|
||||
> UNVERIFIED method/param below before relying on it.
|
||||
|
||||
Verified spec for the methods used by this skill. Sourced from Bitdefender's
|
||||
archived Public API documentation. Methods are flagged **VERIFIED** (signature
|
||||
confirmed and exposed in the CLI) or **UNVERIFIED** (signature not confirmed —
|
||||
@@ -110,7 +115,7 @@ In `getNetworkInventoryItems` results, `type == 1` denotes a company node.
|
||||
|---|---|---|---|
|
||||
| `getPoliciesList` | `page?, perPage?` | VERIFIED | List policies (id, name). |
|
||||
| `getPolicyDetails` | `policyId` | VERIFIED | **Full** granular config (not shallow). |
|
||||
| `assignPolicy` (`/network`) | `policyId, targetIds[], forcePolicyInheritance?` | VERIFIED LIVE (param shape) | Assign existing policy to endpoints/groups. Param shape confirmed via validation probe 2026-06-21. CLI `assign-policy`, gated. STATE-CHANGING. |
|
||||
| `assignPolicy` (`/network`) | `policyId, targetIds[], forcePolicyInheritance?, inheritFromAbove?` | VERIFIED (official docs + probe) | Assign existing policy to endpoints/containers. NOT applied to targets with an ENFORCED policy. CLI `assign-policy`, gated. STATE-CHANGING. Docs: 77212-924802-assignpolicy.html |
|
||||
|
||||
## reports (`/reports`) — VERIFIED LIVE
|
||||
|
||||
@@ -139,7 +144,12 @@ In `getNetworkInventoryItems` results, `type == 1` denotes a company node.
|
||||
|---|---|---|---|
|
||||
| `getPushEventSettings` | `{}` | VERIFIED LIVE | Current settings. CLI `push-settings`. |
|
||||
| `getPushEventStats` | `{}` | VERIFIED LIVE | Delivery stats. CLI `push-stats`. |
|
||||
| `setPushEventSettings` | `status (req), serviceType, serviceSettings{url,requireValidSslCertificate,authorization}, subscribeToEventTypes?` | `status` VERIFIED (probe); nested shape UNVERIFIED | Configure the service. CLI `push-set`, gated. STATE-CHANGING. Needs a receiver URL.
|
||||
| `setPushEventSettings` | `status (req), serviceType, serviceSettings{url,requireValidSslCertificate,authorization}, subscribeToEventTypes{<event flags>}` | VERIFIED (official docs + probe) | Configure the service. `serviceType` ∈ `splunk`/`cef`/`jsonRPC`. Receiver MUST support TLS 1.2+. `subscribeToEventTypes` is a map of event flags (av, fw, aph, registration, task-status, modules, network-sandboxing, antiexploit, dp, uc, …) set true to subscribe. Returns bool. CLI `push-set`, gated. STATE-CHANGING. Needs a receiver URL. Docs: 77209-135319-setpusheventsettings.html
|
||||
|
||||
> Receiver pattern for the webhook (Phase-2): stand up an HTTPS endpoint (TLS
|
||||
> 1.2+, valid cert) that accepts GravityZone's event POSTs — a coord-API route
|
||||
> or an RMM ingest route — then `push-set --status 1 --url <that-endpoint>
|
||||
> --confirm`. `serviceType jsonRPC` posts JSON-RPC event batches.
|
||||
|
||||
## quarantine (`/quarantine`)
|
||||
|
||||
|
||||
@@ -276,7 +276,9 @@ def cmd_assign_policy(client, args):
|
||||
if not _gated(desc, args.confirm):
|
||||
return 3
|
||||
result = client.assign_policy(
|
||||
args.policy, args.targets, force_inheritance=args.force_inheritance
|
||||
args.policy, args.targets,
|
||||
force_inheritance=args.force_inheritance,
|
||||
inherit_from_above=args.inherit_from_above,
|
||||
)
|
||||
_emit({"assignedPolicy": args.policy, "targets": args.targets,
|
||||
"result": result}, args.json, _print_kv)
|
||||
@@ -668,6 +670,8 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
help="One or more endpoint/group ids.")
|
||||
sp.add_argument("--force-inheritance", action="store_true",
|
||||
help="Force policy inheritance to sub-items.")
|
||||
sp.add_argument("--inherit-from-above", action="store_true",
|
||||
help="Inherit the policy from the parent group.")
|
||||
sp.add_argument("--confirm", action="store_true")
|
||||
|
||||
sp = sub.add_parser("push-set",
|
||||
|
||||
@@ -633,17 +633,22 @@ class GravityZoneClient:
|
||||
policy_id: str,
|
||||
target_ids: list[str],
|
||||
force_inheritance: bool = False,
|
||||
inherit_from_above: bool = False,
|
||||
) -> Any:
|
||||
"""Assign an existing policy to endpoints/groups (network.assignPolicy).
|
||||
|
||||
Param shape VERIFIED LIVE via validation probe (2026-06-21): requires
|
||||
`policyId` and `targetIds` (a list of endpoint/group ids).
|
||||
`forcePolicyInheritance` is optional. STATE-CHANGING — gate at the call
|
||||
site behind --confirm.
|
||||
Param shape VERIFIED against the official docs + live validation probe
|
||||
(2026-06-21): `policyId` and `targetIds` (endpoint/container ids) are
|
||||
required; `forcePolicyInheritance` and `inheritFromAbove` are optional
|
||||
bools. NOTE: the policy is NOT applied to targets that already carry an
|
||||
ENFORCED policy. STATE-CHANGING — gate at the call site behind --confirm.
|
||||
Docs: bitdefender.com/business/support/en/77212-924802-assignpolicy.html
|
||||
"""
|
||||
params: dict = {"policyId": policy_id, "targetIds": target_ids}
|
||||
if force_inheritance:
|
||||
params["forcePolicyInheritance"] = True
|
||||
if inherit_from_above:
|
||||
params["inheritFromAbove"] = True
|
||||
return self._jsonrpc_request("network", "assignPolicy", params)
|
||||
|
||||
def list_scan_tasks(
|
||||
|
||||
Reference in New Issue
Block a user