Documentation
¶
Index ¶
- Constants
- func ExtractParamsFromURL(urlStr string) (map[string]string, error)
- func GetResponseHeader(resp *interfaces.Response, key string) string
- func GetResponseHeaders(resp *interfaces.Response) http.Header
- func HasNextPage(links *PaginationLinks) bool
- func IsBadRequest(err error) bool
- func IsNotFound(err error) bool
- func IsResponseError(resp *interfaces.Response) bool
- func IsResponseSuccess(resp *interfaces.Response) bool
- func IsServerError(err error) bool
- func IsUnauthorized(err error) bool
- func NewRSQLFilterBuilder() interfaces.RSQLFilterBuilder
- func ParseErrorResponse(body []byte, statusCode int, status, method, endpoint string, ...) error
- func SetupAuthentication(restyClient *resty.Client, authConfig *AuthConfig, logger *zap.Logger) (*tokenHolder, error)
- type APIError
- type AuthConfig
- type ClientOption
- func WithBaseURL(baseURL string) ClientOption
- func WithDebug() ClientOption
- func WithGlobalHeader(key, value string) ClientOption
- func WithGlobalHeaders(headers map[string]string) ClientOption
- func WithInsecureSkipVerify() ClientOption
- func WithLogger(logger *zap.Logger) ClientOption
- func WithMandatoryRequestDelay(d time.Duration) ClientOption
- func WithMaxConcurrentRequests(n int) ClientOption
- func WithProxy(proxyURL string) ClientOption
- func WithRetryCount(count int) ClientOption
- func WithRetryMaxWaitTime(maxWaitTime time.Duration) ClientOption
- func WithRetryWaitTime(waitTime time.Duration) ClientOption
- func WithTLSClientConfig(tlsConfig *tls.Config) ClientOption
- func WithTimeout(timeout time.Duration) ClientOption
- func WithTotalRetryDuration(d time.Duration) ClientOption
- func WithTransport(transport http.RoundTripper) ClientOption
- func WithUserAgent(userAgent string) ClientOption
- type OTelConfig
- type PaginationLinks
- type Transport
- func (t *Transport) Delete(ctx context.Context, path string, rsqlQuery map[string]string, ...) (*interfaces.Response, error)
- func (t *Transport) DeleteWithBody(ctx context.Context, path string, body any, headers map[string]string, ...) (*interfaces.Response, error)
- func (t *Transport) EnableTracing(config *OTelConfig) error
- func (t *Transport) Get(ctx context.Context, path string, rsqlQuery map[string]string, ...) (*interfaces.Response, error)
- func (t *Transport) GetBytes(ctx context.Context, path string, rsqlQuery map[string]string, ...) (*interfaces.Response, []byte, error)
- func (t *Transport) GetHTTPClient() *resty.Client
- func (t *Transport) GetLogger() *zap.Logger
- func (t *Transport) GetPaginated(ctx context.Context, path string, rsqlQuery map[string]string, ...) (*interfaces.Response, error)
- func (t *Transport) InvalidateToken() error
- func (t *Transport) KeepAliveToken() error
- func (t *Transport) Patch(ctx context.Context, path string, body any, headers map[string]string, ...) (*interfaces.Response, error)
- func (t *Transport) Post(ctx context.Context, path string, body any, headers map[string]string, ...) (*interfaces.Response, error)
- func (t *Transport) PostForm(ctx context.Context, path string, formData map[string]string, ...) (*interfaces.Response, error)
- func (t *Transport) PostMultipart(ctx context.Context, path string, fileField string, fileName string, ...) (*interfaces.Response, error)
- func (t *Transport) PostWithQuery(ctx context.Context, path string, rsqlQuery map[string]string, body any, ...) (*interfaces.Response, error)
- func (t *Transport) Put(ctx context.Context, path string, body any, headers map[string]string, ...) (*interfaces.Response, error)
- func (t *Transport) RSQLBuilder() interfaces.RSQLFilterBuilder
Constants ¶
const ( AuthMethodOAuth2 = "oauth2" AuthMethodBasic = "basic" )
AuthMethod constants for the Jamf Pro authentication methods.
const ( DefaultTimeout = 120 * time.Second MaxRetries = 3 RetryWaitTime = 2 * time.Second RetryMaxWaitTime = 30 * time.Second // DefaultMaxConcurrentRequests is the Jamf-recommended maximum of 5 // concurrent API connections. Set to 0 to use WithMaxConcurrentRequests. DefaultMaxConcurrentRequests = 5 // DefaultPageSize is the number of results fetched per page in GetPaginated. DefaultPageSize = 200 )
HTTP client defaults. Aligned with Jamf Pro API scalability guidance: max 5 concurrent connections, exponential backoff for transient errors.
const ( StatusBadRequest = 400 StatusForbidden = 403 StatusNotFound = 404 StatusConflict = 409 StatusPreconditionFailed = 412 StatusUnprocessableEntity = 422 StatusTooManyRequests = 429 StatusInternalServerError = 500 )
const (
UserAgentBase = "go-sdk-jamfpro-v2"
)
const Version = "0.1.0"
Version is the SDK version.
Variables ¶
This section is empty.
Functions ¶
func ExtractParamsFromURL ¶
ExtractParamsFromURL extracts query parameters from a URL string.
func GetResponseHeader ¶
func GetResponseHeader(resp *interfaces.Response, key string) string
GetResponseHeader returns a header value from the response by key.
func GetResponseHeaders ¶
func GetResponseHeaders(resp *interfaces.Response) http.Header
GetResponseHeaders returns all headers from the response.
func HasNextPage ¶
func HasNextPage(links *PaginationLinks) bool
HasNextPage checks if there is a next page (for link-based pagination).
func IsBadRequest ¶
IsBadRequest checks if the error is a bad request error (400).
func IsNotFound ¶
IsNotFound checks if the error is a not found error (404).
func IsResponseError ¶
func IsResponseError(resp *interfaces.Response) bool
IsResponseError returns true if the response status code is 4xx or 5xx.
func IsResponseSuccess ¶
func IsResponseSuccess(resp *interfaces.Response) bool
IsResponseSuccess returns true if the response status code is 2xx.
func IsServerError ¶
IsServerError checks if the error is a server error (5xx).
func IsUnauthorized ¶
IsUnauthorized checks if the error is an authentication error (401).
func NewRSQLFilterBuilder ¶
func NewRSQLFilterBuilder() interfaces.RSQLFilterBuilder
NewRSQLFilterBuilder returns a new, empty RSQL filter expression builder.
func ParseErrorResponse ¶
func ParseErrorResponse(body []byte, statusCode int, status, method, endpoint string, logger *zap.Logger) error
ParseErrorResponse parses an error response from the API.
func SetupAuthentication ¶
func SetupAuthentication(restyClient *resty.Client, authConfig *AuthConfig, logger *zap.Logger) (*tokenHolder, error)
SetupAuthentication configures the resty client with Jamf Pro bearer token authentication. A token is fetched immediately to surface misconfiguration at startup. Subsequent requests refresh the token automatically via middleware.
Returns the tokenHolder so the Transport can expose InvalidateToken and KeepAliveToken.
See: https://developer.jamf.com/jamf-pro/docs/classic-api-authentication-changes
Types ¶
type APIError ¶
type APIError struct {
Code string
Message string
StatusCode int
Status string
Endpoint string
Method string
}
APIError represents an error response from the Jamf Pro API.
type AuthConfig ¶
type AuthConfig struct {
// InstanceDomain is the Jamf Pro instance base URL (e.g. https://example.jamfcloud.com).
InstanceDomain string
// AuthMethod selects the authentication flow: "oauth2" or "basic".
AuthMethod string
// OAuth2 credentials (required when AuthMethod == "oauth2").
ClientID string
ClientSecret string
// Basic auth credentials (required when AuthMethod == "basic").
Username string
Password string
// TokenRefreshBufferPeriod is how far before expiry to proactively refresh
// the token. Defaults to 5 minutes if zero.
TokenRefreshBufferPeriod time.Duration
// HideSensitiveData suppresses bearer token values in log output.
// Enable in production to prevent tokens from appearing in log files.
HideSensitiveData bool
}
AuthConfig holds authentication configuration for the Jamf Pro API.
Two authentication flows are supported:
- OAuth2 client credentials (recommended): POST /api/v1/oauth/token
- Basic auth to bearer token exchange: POST /api/v1/auth/token
See: https://developer.jamf.com/jamf-pro/docs/classic-api-authentication-changes
func AuthConfigFromEnv ¶
func AuthConfigFromEnv() *AuthConfig
AuthConfigFromEnv builds AuthConfig from environment variables. Required: INSTANCE_DOMAIN, AUTH_METHOD; for oauth2: CLIENT_ID, CLIENT_SECRET; for basic: BASIC_AUTH_USERNAME, BASIC_AUTH_PASSWORD. Optional: TOKEN_REFRESH_BUFFER_SECONDS (default 300), HIDE_SENSITIVE_DATA (default false).
func LoadAuthConfigFromFile ¶
func LoadAuthConfigFromFile(path string) (*AuthConfig, error)
LoadAuthConfigFromFile loads AuthConfig from a JSON file. Expected keys: instance_domain, auth_method; for oauth2: client_id, client_secret; for basic: basic_auth_username, basic_auth_password. Optional: token_refresh_buffer_period_seconds (default 300).
func (*AuthConfig) Validate ¶
func (a *AuthConfig) Validate() error
Validate checks the auth configuration for required fields.
type ClientOption ¶
ClientOption configures the Transport.
func WithBaseURL ¶
func WithBaseURL(baseURL string) ClientOption
WithBaseURL sets a custom base URL for the API client.
func WithDebug ¶
func WithDebug() ClientOption
WithDebug enables debug mode which logs request and response details.
func WithGlobalHeader ¶
func WithGlobalHeader(key, value string) ClientOption
WithGlobalHeader sets a global header included in all requests.
func WithGlobalHeaders ¶
func WithGlobalHeaders(headers map[string]string) ClientOption
WithGlobalHeaders sets multiple global headers at once.
func WithInsecureSkipVerify ¶
func WithInsecureSkipVerify() ClientOption
WithInsecureSkipVerify disables TLS certificate verification (use only for testing).
func WithLogger ¶
func WithLogger(logger *zap.Logger) ClientOption
WithLogger sets a custom logger for the client.
func WithMandatoryRequestDelay ¶
func WithMandatoryRequestDelay(d time.Duration) ClientOption
WithMandatoryRequestDelay sets a fixed delay after every successful request. Use for bulk operations to avoid hitting Jamf Pro rate limits.
func WithMaxConcurrentRequests ¶
func WithMaxConcurrentRequests(n int) ClientOption
WithMaxConcurrentRequests sets the maximum number of concurrent API requests. Jamf Pro guidance recommends no more than 5 concurrent connections to avoid disrupting other Jamf Pro tasks and managed devices. Pass 0 to disable.
func WithProxy ¶
func WithProxy(proxyURL string) ClientOption
WithProxy sets an HTTP proxy for all requests.
func WithRetryCount ¶
func WithRetryCount(count int) ClientOption
WithRetryCount sets the number of retries for failed requests.
func WithRetryMaxWaitTime ¶
func WithRetryMaxWaitTime(maxWaitTime time.Duration) ClientOption
WithRetryMaxWaitTime sets the maximum wait time between retries.
func WithRetryWaitTime ¶
func WithRetryWaitTime(waitTime time.Duration) ClientOption
WithRetryWaitTime sets the wait time between retry attempts.
func WithTLSClientConfig ¶
func WithTLSClientConfig(tlsConfig *tls.Config) ClientOption
WithTLSClientConfig sets custom TLS configuration.
func WithTimeout ¶
func WithTimeout(timeout time.Duration) ClientOption
WithTimeout sets a custom timeout for HTTP requests.
func WithTotalRetryDuration ¶
func WithTotalRetryDuration(d time.Duration) ClientOption
WithTotalRetryDuration sets a maximum total wall-clock budget for a request including all retry attempts. Requests that exceed this duration are cancelled.
func WithTransport ¶
func WithTransport(transport http.RoundTripper) ClientOption
WithTransport sets a custom HTTP transport (http.RoundTripper).
func WithUserAgent ¶
func WithUserAgent(userAgent string) ClientOption
WithUserAgent sets a custom user agent string.
type OTelConfig ¶
type OTelConfig struct {
// TracerProvider is the OpenTelemetry tracer provider to use.
// If nil, the global tracer provider will be used.
TracerProvider trace.TracerProvider
// Propagators is the propagator to use for context propagation.
// If nil, the global propagator will be used.
Propagators propagation.TextMapPropagator
// ServiceName is the name of the service for tracing spans.
// Defaults to "jamfpro-client".
ServiceName string
// SpanNameFormatter allows customizing span names.
// If nil, defaults to "HTTP {method}" format.
SpanNameFormatter func(operation string, req *http.Request) string
}
OTelConfig holds OpenTelemetry configuration options.
func DefaultOTelConfig ¶
func DefaultOTelConfig() *OTelConfig
DefaultOTelConfig returns a default OpenTelemetry configuration.
type PaginationLinks ¶
PaginationLinks contains pagination navigation links (for cursor-style APIs).
type Transport ¶
type Transport struct {
BaseURL string
// contains filtered or unexported fields
}
Transport is the HTTP transport layer for the Jamf Pro API. It wraps a resty.Client with Jamf-specific behaviour: bearer token auth, idempotent-only retries with exponential backoff, adaptive response-time throttling, sticky-session cookie jar, optional concurrency limiting, and structured logging.
func NewTransport ¶
func NewTransport(authConfig *AuthConfig, options ...ClientOption) (*Transport, error)
NewTransport creates and fully configures a Jamf Pro API transport.
Behaviour applied at construction time (resty native where possible):
- Bearer token authentication with automatic refresh
- Idempotent-only retry (GET/PUT/DELETE) with exponential backoff
- Sticky-session cookie jar (handles jpro-ingress, APBALANCEID, JSESSIONID)
- Deprecation header warning logged on every response
- Adaptive inter-request delay derived from response-time EMA tracking
Jamf Pro does not emit rate-limit HTTP headers. Throttling is inferred from observed response times per Jamf scalability best practices.
func (*Transport) Delete ¶
func (t *Transport) Delete(ctx context.Context, path string, rsqlQuery map[string]string, headers map[string]string, result any) (*interfaces.Response, error)
Delete executes a DELETE request.
func (*Transport) DeleteWithBody ¶
func (t *Transport) DeleteWithBody(ctx context.Context, path string, body any, headers map[string]string, result any) (*interfaces.Response, error)
DeleteWithBody executes a DELETE request with a JSON body.
func (*Transport) EnableTracing ¶
func (t *Transport) EnableTracing(config *OTelConfig) error
EnableTracing wraps the HTTP client transport with OpenTelemetry instrumentation. This provides automatic tracing for all HTTP requests made by the client.
The instrumentation captures: - HTTP method, URL, status code - Request and response headers (configurable) - Error details - Request/response timing
All spans follow OpenTelemetry semantic conventions for HTTP clients.
func (*Transport) Get ¶
func (t *Transport) Get(ctx context.Context, path string, rsqlQuery map[string]string, headers map[string]string, result any) (*interfaces.Response, error)
Get executes a GET request.
func (*Transport) GetBytes ¶
func (t *Transport) GetBytes(ctx context.Context, path string, rsqlQuery map[string]string, headers map[string]string) (*interfaces.Response, []byte, error)
GetBytes performs a GET request and returns raw bytes without unmarshaling.
func (*Transport) GetHTTPClient ¶
GetHTTPClient returns the underlying resty client for advanced use.
func (*Transport) GetPaginated ¶
func (t *Transport) GetPaginated(ctx context.Context, path string, rsqlQuery map[string]string, headers map[string]string, mergePage func(pageData []byte) error) (*interfaces.Response, error)
GetPaginated executes a paginated GET request, transparently fetching all pages and merging them via the caller-supplied mergePage function.
Jamf Pro paginated endpoints return a JSON envelope with "totalCount" and "results". Page numbering is zero-based; page-size defaults to DefaultPageSize. rsqlQuery may include:
- "filter" – RSQL expression to narrow results (use RSQLBuilder)
- "sort" – sort field and direction (e.g. "general.name:asc")
- "page" – override starting page (default 0)
- "page-size" – override page size (default DefaultPageSize)
Pagination is only available on endpoints that explicitly support it. Example: GET /api/v3/computers-inventory See: https://developer.jamf.com/jamf-pro/reference/get_v3-computers-inventory
func (*Transport) InvalidateToken ¶
InvalidateToken revokes the current bearer token at the Jamf Pro API and clears the local cache. The next request triggers a full re-authentication.
func (*Transport) KeepAliveToken ¶
KeepAliveToken extends the current bearer token lifetime without re-auth. Use before long-running operations to prevent mid-operation token expiry.
func (*Transport) Patch ¶
func (t *Transport) Patch(ctx context.Context, path string, body any, headers map[string]string, result any) (*interfaces.Response, error)
Patch executes a PATCH request.
func (*Transport) Post ¶
func (t *Transport) Post(ctx context.Context, path string, body any, headers map[string]string, result any) (*interfaces.Response, error)
Post executes a POST request with JSON body.
func (*Transport) PostForm ¶
func (t *Transport) PostForm(ctx context.Context, path string, formData map[string]string, headers map[string]string, result any) (*interfaces.Response, error)
PostForm executes a POST request with form-urlencoded data.
func (*Transport) PostMultipart ¶
func (t *Transport) PostMultipart(ctx context.Context, path string, fileField string, fileName string, fileReader io.Reader, fileSize int64, formFields map[string]string, headers map[string]string, progressCallback interfaces.MultipartProgressCallback, result any) (*interfaces.Response, error)
PostMultipart executes a POST request with multipart/form-data.
func (*Transport) PostWithQuery ¶
func (t *Transport) PostWithQuery(ctx context.Context, path string, rsqlQuery map[string]string, body any, headers map[string]string, result any) (*interfaces.Response, error)
PostWithQuery executes a POST request with both body and query parameters.
func (*Transport) Put ¶
func (t *Transport) Put(ctx context.Context, path string, body any, headers map[string]string, result any) (*interfaces.Response, error)
Put executes a PUT request.
func (*Transport) RSQLBuilder ¶
func (t *Transport) RSQLBuilder() interfaces.RSQLFilterBuilder
RSQLBuilder returns a new RSQL filter expression builder. Pass the Build() result as rsqlQuery["filter"] to filter endpoint results.