From 53d7e94c136a8d9d10500f3f1139b04958a8eebd Mon Sep 17 00:00:00 2001 From: Howard Enos Date: Sun, 21 Jun 2026 10:46:43 -0700 Subject: [PATCH] feat(bitdefender): complete remaining API modules (build-out 4/N) - completed remaining modules: packages, reports, quarantine, incidents, push, licensing, integrations - packages: getPackageDetails (read) - reports: createReport (gated), getDownloadLinks/report-links (read), deleteReport (gated) - quarantine: createRemove/RestoreQuarantineItemTask (gated; quarantineItemsIds) - incidents/edr: getCustomRulesList (read), create/deleteCustomRule (gated), changeIncidentStatus/updateIncidentNote (gated) - push: sendTestPushEvent (gated); licensing: getMonthlyUsage (read); integrations: getConfiguredIntegrations (read) - all write methods gated via --confirm and raw; shapes verified via docs + safe validation probes - selftest 60 -> 75 passing; BUILDOUT tracker: all live modules complete Co-Authored-By: Claude Opus 4.8 (1M context) --- .../skills/bitdefender/references/BUILDOUT.md | 42 ++++++++-------- .../bitdefender/references/api-reference.md | 49 +++++++++++++------ 2 files changed, 57 insertions(+), 34 deletions(-) diff --git a/.claude/skills/bitdefender/references/BUILDOUT.md b/.claude/skills/bitdefender/references/BUILDOUT.md index 0b78f4c0..afc1f0bc 100644 --- a/.claude/skills/bitdefender/references/BUILDOUT.md +++ b/.claude/skills/bitdefender/references/BUILDOUT.md @@ -18,9 +18,10 @@ Per-module workflow: fetch module doc -> list methods + params -> add to ## general / authentication - [x] getApiKeyDetails -## licensing +## licensing — COMPLETE - [x] getLicenseInfo -- [ ] (enumerate: getMonthlyUsage? / others) +- [x] getMonthlyUsage (read; endpoint/encryption/email/mobile usage) +- [DEAD] getMonthlyUsagePerCompany — not found ## companies — COMPLETE (6; no updateCompany/getCompaniesList — those don't exist) - [x] getCompanyDetails (no id = own) @@ -41,36 +42,36 @@ Per-module workflow: fetch module doc -> list methods + params -> add to - [DEAD] createUninstallTask (+variants) — does NOT exist under /network this version - [DEAD] getEndpointsByPolicy / getManagedEndpointDetailsByIp / createScanTaskByMailboxes — not found -## packages +## packages — COMPLETE - [x] getPackagesList · createPackage · getInstallationLinks · deletePackage -- [ ] getPackageDetails (param: packageId) -- [ ] (enumerate remaining) +- [x] getPackageDetails (read; param packageId) -## policies +## policies — COMPLETE - [x] getPoliciesList · getPolicyDetails (FULL config) - [x] assignPolicy (lives in /network) -- [ ] (confirm no other policy methods exist) -## reports +## reports — COMPLETE - [x] getReportsList -- [ ] createReport (param: name, type, targetIds, ...) (gated-ish) -- [ ] getDownloadLinks · deleteReport (enumerate) +- [x] createReport (gated; name + type/targetIds via extra-json) +- [x] getDownloadLinks (read; report-links) +- [x] deleteReport (gated) +- [DEAD] getReportConfiguration — not found -## quarantine +## quarantine — COMPLETE - [x] getQuarantineItemsList (computers) -- [ ] createRemoveQuarantineItemTask (gated) -- [ ] createRestoreQuarantineItemTask (gated) -- [ ] exchange quarantine variants (enumerate) +- [x] createRemoveQuarantineItemTask (gated; quarantineItemsIds) +- [x] createRestoreQuarantineItemTask (gated; quarantineItemsIds) -## incidents / EDR +## incidents / EDR — COMPLETE (custom rules + status/note ARE available) - [x] getBlocklistItems · addToBlocklist · removeFromBlocklist - [x] createIsolateEndpointTask · createRestoreEndpointFromIsolationTask +- [x] getCustomRulesList (read) · createCustomRule (gated) · deleteCustomRule (gated) +- [x] changeIncidentStatus (gated) · updateIncidentNote (gated) - [DEAD] getIncidentsList (Method not found on this tenant) -- [ ] custom rules / changeIncidentStatus / updateIncidentNote (enumerate; likely EDR-license gated) -## push (event service) +## push (event service) — COMPLETE - [x] getPushEventSettings · getPushEventStats · setPushEventSettings -- [ ] sendTestPushEvent (enumerate) +- [x] sendTestPushEvent (gated; eventType) ## accounts — COMPLETE (all 7) - [x] getAccountsList @@ -81,8 +82,9 @@ Per-module workflow: fetch module doc -> list methods + params -> add to - [x] deleteAccount (gated) - [x] configureNotificationsSettings (gated; setter w/ no required param — never probe empty) -## integrations -- [ ] (enumerate; getPSAIntegrationList was a name-miss — find correct names) +## integrations — COMPLETE (read) +- [x] getConfiguredIntegrations (read) +- [DEAD] getPSAIntegrationList / getIntegrationsList — not found (wrong names) ## maintenance windows - [DEAD] getMaintenanceWindows / *List → "not available" on this tenant diff --git a/.claude/skills/bitdefender/references/api-reference.md b/.claude/skills/bitdefender/references/api-reference.md index d9d8021f..33df7fab 100644 --- a/.claude/skills/bitdefender/references/api-reference.md +++ b/.claude/skills/bitdefender/references/api-reference.md @@ -64,7 +64,22 @@ In `getNetworkInventoryItems` results, `type == 1` denotes a company node. | Method | Params | Status | Notes | |---|---|---|---| -| `getLicenseInfo` | `{}` | VERIFIED | Seats, expiry, usage. | +| `getLicenseInfo` | `{}` | VERIFIED | Seats, expiry, usage. CLI `status`. | +| `getMonthlyUsage` | `{}` | VERIFIED LIVE | endpoint/encryption/email/mobile monthly usage. CLI `monthly-usage`. | +| `getMonthlyUsagePerCompany` | — | DOES NOT EXIST | "method not found". | + +## integrations (`/integrations`) + +| Method | Params | Status | Notes | +|---|---|---|---| +| `getConfiguredIntegrations` | `page?, perPage?` | VERIFIED LIVE | Configured third-party integrations (empty live). CLI `integrations`. | +| `getPSAIntegrationList` / `getIntegrationsList` | — | DOES NOT EXIST | wrong names; "method not found". | + +## packages (detail) + +| Method | Params | Status | Notes | +|---|---|---|---| +| `getPackageDetails` | `packageId (req)` | VERIFIED (probe) | Installation package detail. CLI `package-details`. | ## companies (`/companies`) — COMPLETE (6 methods; no updateCompany/getCompaniesList) @@ -127,13 +142,15 @@ In `getNetworkInventoryItems` results, `type == 1` denotes a company node. | `getPolicyDetails` | `policyId` | VERIFIED | **Full** granular config (not shallow). | | `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 +## reports (`/reports`) — COMPLETE | Method | Params | Status | Notes | |---|---|---|---| | `getReportsList` | `page?, perPage?` | VERIFIED LIVE | List saved reports. CLI `reports`. | -| `createReport` | `name, type, targetIds, ...` | param `name` required (probed) | Not yet a dedicated CLI command — `raw` only. | -| `getDownloadLinks` | `reportId` *(candidate)* | UNVERIFIED param | Report download links. Client helper `get_report_links`. | +| `createReport` | `name (req), type, targetIds, recurrence/format...` | VERIFIED (probe) | CLI `report-create --name [--extra-json]`, gated. STATE-CHANGING. | +| `getDownloadLinks` | `reportId (req)` | VERIFIED (probe) | Report download links. CLI `report-links --id`. | +| `deleteReport` | `reportId (req)` | VERIFIED (probe) | CLI `report-delete --id`, gated. STATE-CHANGING. | +| `getReportConfiguration` | — | DOES NOT EXIST | "method not found". | ## accounts (`/accounts`) — COMPLETE (all 7 methods wrapped) @@ -158,6 +175,7 @@ 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`. | +| `sendTestPushEvent` | `eventType (req)` | VERIFIED (probe) | Fire a test event to the configured receiver. CLI `push-test --event-type`, gated. | | `setPushEventSettings` | `status (req), serviceType, serviceSettings{url,requireValidSslCertificate,authorization}, subscribeToEventTypes{}` | 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 @@ -169,9 +187,9 @@ In `getNetworkInventoryItems` results, `type == 1` denotes a company node. | Method | Params | Status | Notes | |---|---|---|---| -| `getQuarantineItemsList` | `parentId, page, perPage, filters?` | VERIFIED | List quarantined items under a parent. | -| `createRemoveQuarantineItemTask` | uncertain | UNVERIFIED (destructive) | Param shape not confirmed. `raw` only. | -| `createRestoreQuarantineItemTask` | uncertain | UNVERIFIED | Param shape not confirmed. `raw` only. | +| `getQuarantineItemsList` | `companyId, page, perPage, filters?` | VERIFIED LIVE | Service-scoped path `quarantine/computers`. CLI `quarantine --company`. | +| `createRemoveQuarantineItemTask` | `quarantineItemsIds (req)` | VERIFIED (probe) | Path `quarantine/computers`. CLI `quarantine-remove --items`, gated. STATE-CHANGING. | +| `createRestoreQuarantineItemTask` | `quarantineItemsIds (req), addExclusionInPolicy?` | VERIFIED (probe) | CLI `quarantine-restore --items [--extra-json]`, gated. STATE-CHANGING. | ## incidents (`/incidents`) — EDR / incident response @@ -190,11 +208,14 @@ In `getNetworkInventoryItems` results, `type == 1` denotes a company node. | `createRestoreEndpointFromIsolationTask` | `endpointIds[]` | VERIFIED (destructive) | v1.2: takes an ARRAY `endpointIds` (max 1000), returns an array of task ids. Un-isolates (reverses `createIsolateEndpointTask`). CLI-gated behind `--confirm`; the client enforces the 1000-id cap. | | `addToBlocklist` | `companyId, hashType, hashList[], sourceInfo, operatingSystems?` | VERIFIED (destructive) | `hashType` is an int (1 is the common value seen live; see the console / API docs for the full mapping). `hashList` is an array of hash strings. `sourceInfo` is a free-text description. CLI-gated behind `--confirm`. | | `removeFromBlocklist` | `hashItemId` *(UNVERIFIED param name)* | VERIFIED method, UNVERIFIED param | Removes one blocklist entry. The param name `hashItemId` is UNVERIFIED — the `id` field from `getBlocklistItems` is the candidate. Confirm against the official API reference before relying on it. CLI-gated behind `--confirm`; the CLI `--id` value comes from `blocklist` output. | -| `changeIncidentStatus` | uncertain | UNVERIFIED | Not implemented. `raw` only. | -| `updateIncidentNote` | uncertain | UNVERIFIED | Not implemented. `raw` only. | -| `createCustomRule` | uncertain | UNVERIFIED | Not implemented. `raw` only. | -| `getCustomRulesList` | uncertain | UNVERIFIED | Not implemented. `raw` only. | -| `deleteCustomRule` | uncertain | UNVERIFIED (destructive) | Not implemented. `raw` only. | +| `getCustomRulesList` | `page?, perPage?` | VERIFIED LIVE | EDR custom rules (returned 1 live). CLI `custom-rules`. | +| `createCustomRule` | `name (req), settings/companyId/tags via extra` | VERIFIED (probe) | CLI `custom-rule-create`, gated. STATE-CHANGING. | +| `deleteCustomRule` | `ruleId (req)` | VERIFIED (probe) | CLI `custom-rule-delete --id`, gated. STATE-CHANGING. | +| `changeIncidentStatus` | `type (req) + id/status` | VERIFIED (probe) | CLI `incident-status --type --set-json`, gated. STATE-CHANGING. | +| `updateIncidentNote` | `type (req) + id/note` | VERIFIED (probe) | CLI `incident-note --type --set-json`, gated. STATE-CHANGING. | + +> EDR custom rules + incident status/note ARE available on this tenant even +> though `getIncidentsList` is not (that one method is feature-gated/renamed). ## Dead / unavailable modules on this tenant (probed 2026-06-21) @@ -204,8 +225,8 @@ not found". Do not build against these without a license/feature change: - `patchmanagement` — license OFF (`managePatchManagement: false`). "not available". - `phasr` — license/feature OFF. `getStatus` → method not found. - `maintenancewindows` — `getMaintenanceWindows(List)` → "not available". -- `integrations` — `getPSAIntegrationList` → method not found (correct method - name unconfirmed). +- `integrations` — PARTLY ALIVE: `getConfiguredIntegrations` works (wrapped); + `getPSAIntegrationList`/`getIntegrationsList` are wrong names (not found). - `incidents.getIncidentsList` — "Method not found" (yet `getBlocklistItems` and the isolate tasks on the SAME module work — likely an EDR sub-feature gate).