platform

package
v1.30.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 16, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrNoPlatformClient = errors.New("this command requires platform gateway auth")

ErrNoPlatformClient is returned, wrapped, when no platform client could be built. It exists so a caller that knows *why* one is missing can add that reason: the message below lists the credentials to supply, and there is one path where every one of them is already present and only the scope level was dropped. See AnnotateScopeLevelError.

View Source
var ErrNotFound = errors.New("not found")

ErrNotFound is returned when a resource name cannot be resolved to an ID.

Callers should prefer the SDK's built-in resolver methods directly:

blueprints.New(c).ResolveBlueprintIDByName(ctx, name)
compliancebenchmarks.New(c).ResolveBenchmarkIDByName(ctx, name)
compliancebenchmarks.New(c).ResolveBaselineIDByName(ctx, name)
devicegroups.New(c).ResolveDeviceGroupIDByName(ctx, name)
devices.New(c).ResolveDeviceIDByName(ctx, name)
devices.New(c).ResolveDeviceIDBySerialNumber(ctx, serial)

The SDK constructs subpackage clients cheaply (just a transport pointer), so per-call instantiation is fine. ErrNotFound stays here for use in platform.IsNotFound assertions across the codebase.

Functions

func ApplyName added in v1.29.0

func ApplyName(body any, field string) (string, error)

ApplyName reads the human-readable name out of a request body assembled by ReadBody, for the generated `apply` commands.

apply's contract is that the input is the desired state and carries its own identity, so the name comes from the body rather than a flag: a --name flag beside it would be a second source of truth, and the two disagreeing has no correct resolution. That makes "the body has no name" a usage error worth a specific message — without one the failure surfaces further down as a create that the server rejects for a missing required field, or worse as an unintended create because an empty name resolved to nothing.

The value must be a non-empty string. A name that arrives as a number or a null is rejected here rather than coerced: apply matches it against list results, and "1" matching an item whose name is the integer 1 is a coincidence, not a resolution.

func ConfirmAction added in v1.15.0

func ConfirmAction(action, target string, yes bool) error

ConfirmAction prompts the user to confirm a destructive action. Returns nil on confirmation, an error otherwise. When stdin is not a terminal (e.g. CI), requires the --yes flag (yes==true) and returns an error if it isn't set.

Generated platform commands call this for destructive actions (delete, erase, etc.) before performing the request.

func DoExpectDocumented added in v1.28.0

func DoExpectDocumented(
	ctx context.Context,
	client *jamfplatform.Client,
	method, path string,
	body any,
	expectedStatus int,
	documented []DocumentedStatus,
	result any,
) error

DoExpectDocumented performs a request whose failure statuses include some the endpoint documents as answers, and renders their body as the result instead of letting them become an exit-code error.

Jamf Security Cloud's DNS search domain is the case this exists for: the tenant either has a search domain or it does not, and "does not" is answered as 404 SEARCH_DOMAIN_NOT_SET. Reported as an error, the ordinary empty state of a singleton settings endpoint exited 1 and printed a traceId, so a script asking "is a search domain configured?" could not tell "no" from "the request broke".

Mirrors documentedStatusResults in the Jamf Pro generator, which does the same job through registry.WithAllowedStatuses; the platform transport has no allowed-status hook, so the mapping happens here on the way back out.

func IsNotFound

func IsNotFound(err error) bool

IsNotFound reports whether err is or wraps ErrNotFound, or is a 404 *APIResponseError from the Platform SDK (returned by Resolve* methods when a name lookup yields zero results).

func PrintList

func PrintList[T any](out registry.OutputFormatter, items []T) error

PrintList outputs a list of items through the CLI formatter.

func PrintOne

func PrintOne[T any](out registry.OutputFormatter, item T) error

PrintOne outputs a single item through the CLI formatter.

func ReadBody added in v1.15.0

func ReadBody(file string, sets []string) (any, error)

ReadBody assembles a JSON-marshallable request body from --from-file (a JSON or YAML file path, or piped stdin when the flag is absent) and --set overrides ("key=value", "nested.key=value"). When no body is supplied an empty object is the starting point. Set values are JSON-decoded when they look like JSON (true/false/null/number/[]/{}/"...") and treated as strings otherwise. Dot-separated keys descend into nested maps.

Generated platform commands call this for POST/PATCH bodies. Returns nil when there's nothing to send (no input, no overrides) so callers can decide whether the op accepts an empty body or should error.

func ReportDryRun added in v1.28.0

func ReportDryRun(w io.Writer, method, path string, body any) error

ReportDryRun prints the request a mutating command would have sent and reports nothing else, so the caller can return nil without touching the API.

Generated commands call this instead of the transport when --dry-run is set. The gate has to live in the command rather than in the HTTP layer because the platform transport asserts an exact success status: a synthetic response invented down there would have to guess 200 vs 201 vs 204 per operation and would fail the assertion whenever it guessed wrong, turning a preview into an error. The command already knows the method, the resolved path and the body.

Output goes to w (stderr for real commands) so a dry run cannot be mistaken for command output on a pipe.

func RequirePlatformClient added in v1.15.0

func RequirePlatformClient(client *jamfplatform.Client) error

RequirePlatformClient returns a descriptive error when client is nil. Generated platform commands call this at the top of RunE so users get clear setup guidance instead of a nil-pointer panic.

func ResolveIDByName added in v1.15.0

func ResolveIDByName(ctx context.Context, client *jamfplatform.Client, listPath string, name string) (string, error)

ResolveIDByName finds a resource ID by its human-readable name on a Platform list endpoint. Walks pages when the response is paginated. Generated commands call this when the user supplies --name instead of a positional ID.

The list response can take several shapes:

  • {"results": [...], "totalCount": N} — paginated (blueprints, devices)
  • {"<resource>": [...]} — non-paginated single-array (baselines)
  • [...] — bare array

listPath is the full gateway path, /{service}/v{n}/<collection>. There is no /api segment and no tenant segment: the GA gateway mounts each namespace at the root, and the scope travels as an X-Tenant-Id or X-Environment-Id header set by the transport. Items are matched by checking "name", "title", and "displayName" properties in that order. The ID is read from "id" (and falls back to "blueprintId", "groupId", "deviceId" for resources that use a non-standard ID field).

Returns an error when multiple items share the name (ambiguous match within a single page). Use ResolveIDByNameFiltered to narrow the lookup first.

func ResolveIDByNameFiltered added in v1.18.0

func ResolveIDByNameFiltered(ctx context.Context, client *jamfplatform.Client, listPath string, name string, filter string) (string, error)

ResolveIDByNameFiltered is like ResolveIDByName but narrows the server-side results with an RSQL filter expression appended as ?filter=<expr> before the name walk begins. Pass an empty string for no additional filtering.

Example: ResolveIDByNameFiltered(ctx, c, path, "My Group", `deviceType=="COMPUTER"`)

func ResolveIDByNameInField added in v1.28.0

func ResolveIDByNameInField(ctx context.Context, client *jamfplatform.Client, listPath, name, nameField string) (string, error)

ResolveIDByNameInField is ResolveIDByName with one extra property consulted ahead of the standard three.

Some resources carry their human-readable identifier under a field of their own: an SSO domain's is "domain", so a --name lookup against the domains collection matched nothing and reported "no item with name …" — indis- tinguishable from a typo, on a resource whose only other handle is an opaque integer ID. The extra field is named per resource by the generator's platformNameLookupFields table rather than added to defaultNameFields, because a global "domain" match would let a resource that happens to carry an unrelated domain property resolve on it.

func SelectTableColumns added in v1.15.0

func SelectTableColumns(data []byte, columns []TableColumn, format string) []byte

SelectTableColumns transforms a JSON array to include only the configured columns. For JSON/YAML/raw output formats, the input is returned unchanged so full fidelity is preserved.

Types

type DocumentedStatus added in v1.28.0

type DocumentedStatus struct {
	Code      int
	ErrorCode string
	// Empty marks a status that means "this is not configured" rather than
	// carrying an answer in its body. The response is an error envelope
	// ({httpStatus, traceId, errors}), not the shape the endpoint returns when
	// the setting exists, so rendering it would make one command emit two
	// unrelated schemas depending on state — and its traceId changes per call,
	// so the output would not even be stable between two identical reads.
	// An empty object is rendered instead: same schema family, deterministic,
	// and every field the caller would read comes back null.
	Empty bool
}

DocumentedStatus names a non-2xx response that an operation documents as a *result* rather than a failure: the status the server answers, and the error code its body must carry for that reading to apply.

The error code is part of the match on purpose. Allowing a bare status would mean any 404 on the endpoint renders as success, including one caused by a path or tenant mistake, and a wrong answer with a zero exit code is the failure mode that is hardest to notice.

type TableColumn added in v1.15.0

type TableColumn struct {
	Field string // dot-notation JSON path (e.g. "deploymentState.state")
	Label string // output key/header
}

TableColumn defines a column selection for list table output.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL