⭐ Add jamf provider#7144
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
/review |
There was a problem hiding this comment.
Review: Nil Handling, Performance, and Logic
Nil Handling
1. No nil checks on any API response. Every resource file dereferences the SDK return value without checking for nil. If any Jamf SDK method returns (nil, nil), these all panic:
sso_settings.go—info.SsoEnabledcomputer_inventory.go—inventory.Resultscomputer_inventory.go:localUserAccounts()—inventory.LocalUserAccountscomputer_groups.go—groups.Resultsusers.go—users.Userspackages.go—inventory.Resultsuser_by_name.go—user.ID,user.Name, etc.version.go—info.Versionis nil-checked, butinfoitself is not
2. Nested struct dereferences in computer_inventory.go. c.General.Name, c.Hardware.Make, c.OperatingSystem.Name, c.Security.AutoLoginDisabled — if any sub-struct (General, Hardware, OperatingSystem, Security) is nil, this panics. The Jamf API can return partial records.
3. sso() returns a singular resource pointer (*mqlSsoSettings). If this ever needs to return nil (e.g., SSO not configured, access denied), it must set a.Sso.State = plugin.StateIsSet | plugin.StateIsNull before return nil, nil. See CLAUDE.md "Never return nil, nil from a singular resource accessor without setting StateIsNull first."
Logic Errors
4. ParseCLI leaks client secret into plaintext conf.Options. (provider.go:55-56):
conf.Options["client_secret"] = clientSecretThe secret already flows through conf.Credentials — storing it again in Options means it could be logged, serialized, or exposed in debug output. Remove client_id and client_secret from conf.Options.
5. ParseCLI env var fallback is tangled. (provider.go:60-74) When credentials come from env vars, the local variables are populated but conf.Options is only partially updated. Consider restructuring: resolve all sources (flags then env) first, then populate conf once at the end.
6. __id is never set in any CreateResource call. Per codebase conventions, __id must be explicitly set for caching. Without it, the runtime can't cache resources and the same API object fetched twice won't get a cache hit. Every CreateResource call needs:
"__id": llx.StringData("some-unique-stable-id"),7. Fragile id() cache keys — using names instead of unique IDs.
mqlComputerGroups.id()returnsName.Data— group names aren't guaranteed uniquemqlJamfPackages.id()returnsName.Data— package names can collidemqlJamfUsers.id()returnsName.Data— should use numeric ID (strconv.Itoa)
Use the actual unique ID field (formatted as string) for reliable caching.
8. Resource naming inconsistency in jamf.lr. Mixed prefixing and pluralization: jamfComputer, jamfPackages (plural), jamfUsers (plural), ssoSettings (no prefix), computerGroups (no prefix). Resource types should be singular and consistently named.
Performance
9. computerInventory() has no pagination. (computer_inventory.go:24) GetComputersInventory(url.Values{}) is called with empty params. The Jamf Pro inventory API is paginated — this will silently return only the first page. Customers with more computers than the default page size will get incomplete data. Must loop with page/page-size params.
10. computerInventoryCount() fetches ALL inventory records just to count them. (computer_inventory_count.go) It calls r.GetComputerInventory() which triggers the full inventory fetch, then counts the slice length. Jamf has a dedicated count endpoint — use it instead.
11. localUserAccounts() triggers N+1 API calls. Each jamfComputer.localUserAccounts call hits GetComputerInventoryByID. When iterating all computers' accounts, that's N additional API calls. Consider fetching local accounts in the initial inventory call if the SDK supports a section filter.
tas50
left a comment
There was a problem hiding this comment.
Address the issues in the comment and let's see if we can get a testing doc for the provider in place so it's easy for folks to check this.
Also it needs tests.
…ex, docs Resolves the open review feedback on #7144: - Add id() / __id for jamf.localUserAccount (computer + uid + username), jamf.ssoSettings (singleton), and jamf.userByName (name-keyed) so the runtime can cache them correctly. - Rename env vars to JAMF_CLIENT_ID, JAMF_CLIENT_SECRET, and JAMF_INSTANCE_DOMAIN to avoid colliding with other tools/providers. - Protect the per-computer localUserAccounts cache on JamfConnection with sync.RWMutex. - Expand the jamf and jamf.userByName resource doc-comments to the two-part title + description form required by CLAUDE.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A first-PR provider whose Version hasn't shipped should use that version for every .lr.versions entry, not version+1 — the "next patch" rule only applies to additive changes after a release. Came up on the jamf provider review (#7144) where 13.0.0 was correct for the initial cut. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
/review |
Address review feedback on PR #7144: - Replace fragile len(args) > 1 short-circuit with explicit args["id"] check so the "already hydrated" path is self-documenting. - Guard against a nil ResourceUser from GetUserByName before dereferencing its fields. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
b50ada6 to
7c4b062
Compare
|
/review |
66afea7 to
71b85bf
Compare
Adds a new Jamf Pro provider to mql, enabling queries against Jamf-managed infrastructure via the Jamf Pro API. Authentication uses OAuth2 client credentials (flags or JAMF_CLIENT_ID / JAMF_CLIENT_SECRET / JAMF_INSTANCE_DOMAIN env vars). Resources: - jamf — root, exposes computerInventory, computerInventoryCount, packages, sso, version, users, computerGroups - jamf.computer — computer inventory record (hardware, OS, security posture, enrollment state, local user accounts) - jamf.computer.localUserAccount — local user account on a managed Mac - jamf.package — software package definition - jamf.ssoSettings — SSO configuration (singleton) - jamf.computerGroup — smart or static computer group - jamf.user — Jamf user directory entry - jamf.userByName — lookup a Jamf user by username via init() Also bumps go-git/v5 transitively in the jamf module to address GHSA-3xc5-wrhm-f963, and fixes a stale cnquery/v9 reference in the mql scan command output. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Adds a new Jamf Pro provider to mql, enabling querying of Jamf-managed infrastructure via the Jamf Pro API.
Usage
Connect using OAuth2 client credentials and your Jamf Pro instance domain:
Credentials can also be provided via environment variables:
CLIENT_ID,CLIENT_SECRET,INSTANCE_DOMAIN.Example queries
New resources
jamfjamfComputerjamfComputer.localUserAccountsjamf.userByNameinitfor direct queries)jamfUsersjamfPackagesssoSettingscomputerGroups