adminclient

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Sep 3, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package adminclient is the typed HTTP client mdmctl uses against the reference server's admin API.

Why

It exists so the CLI has one place that knows about bearer tokens, error bodies, and cursors, and so those are testable without a process. Three properties matter, and each answers something a reference CLI got wrong: a response body is handed back byte for byte so canonical JSON survives to jq, where nanohubctl re-indents it; cursors are followed on request, where none of the reference CLIs paginate at all; and a redirect is refused, so a bearer token cannot be replayed to a host the operator did not name.

References

  • Decision record: docs/research/decisions/0035-mdmctl-structure-and-credentials.md
  • Decision record: docs/research/decisions/0034-admin-api-and-authorization.md
  • Plan of record: docs/research/implementation_plan.md (phase 8)
  • RFC 6750: bearer token usage

Index

Constants

View Source
const DefaultTimeout = 30 * time.Second

DefaultTimeout bounds one request.

View Source
const MaxBody = 32 << 20

MaxBody bounds a response body, so a hostile or broken server cannot make the CLI buffer without limit.

View Source
const Prefix = "/admin/v1"

Prefix is the admin API root every path is relative to.

Variables

View Source
var (
	// ErrUnauthorized is a 401: no credential, or one the server does not know.
	ErrUnauthorized = errors.New("adminclient: unauthorized")
	// ErrForbidden is a 403: authenticated, but no policy permits it.
	ErrForbidden = errors.New("adminclient: forbidden")
	// ErrNotFound is a 404, which on this API may also mean the route is not
	// served by the role the process is running.
	ErrNotFound = errors.New("adminclient: not found")
	// ErrStatus is any other unsuccessful status.
	ErrStatus = errors.New("adminclient: request failed")
	// ErrConfig is a malformed server URL or missing credential.
	ErrConfig = errors.New("adminclient: bad configuration")
)

Errors callers distinguish.

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client talks to one server.

func New

func New(cfg Config) (*Client, error)

New validates cfg and returns a Client.

func (*Client) Do

func (c *Client) Do(ctx context.Context, method, path string, query url.Values, body any) (*Response, error)

Do issues one request. path is relative to the admin prefix, for example "/principals" or "/declarations/com.example.a".

func (*Client) Each

func (c *Client) Each(ctx context.Context, path string, query url.Values, fn func(jsontext.Value) error) error

Each calls fn for every item of a paged listing, following NextCursor until the server stops returning one. None of the reference admin CLIs paginate, so a large fleet silently truncates for them.

fn receives each item's raw JSON, unmodified.

func (*Client) Page

func (c *Client) Page(ctx context.Context, path string, query url.Values) ([]jsontext.Value, string, error)

Page fetches one page and returns its items and the next cursor.

func (*Client) ServerConfig

func (c *Client) ServerConfig(ctx context.Context) (*ServerConfig, error)

ServerConfig fetches GET /config.

type Config

type Config struct {
	// BaseURL is the server root, without the admin prefix.
	BaseURL string
	// Token is the bearer credential.
	Token string
	// Timeout bounds one request; zero uses DefaultTimeout.
	Timeout time.Duration
	// Insecure skips TLS verification. The CLI warns on every use.
	Insecure bool
	// HTTPClient overrides the transport, for tests.
	HTTPClient *http.Client
	// Trace receives one line per request, with the token never included.
	Trace func(string)
}

Config builds a Client.

type Response

type Response struct {
	Status int
	Body   []byte
}

Response is one admin API answer. Body is the server's bytes, unmodified, so canonical JSON and key order survive to whatever consumes them.

type Route

type Route struct {
	Method, Pattern, Action, Family string
}

Route is one entry of the server's route table.

type ServerConfig

type ServerConfig struct {
	Role     string
	Version  string
	Families []string
	Routes   []Route
	// Policy reports a principal and Cedar policy store.
	Policy bool
	// BreakGlass reports that the static MDM_ADMIN_TOKEN is still accepted.
	BreakGlass bool
}

ServerConfig describes the server: its role, the route families it serves, the version, and which admin credentials it accepts. The CLI reads it to explain a 404 that is really a role split, and to report a break-glass token that outlived its bootstrap.

Jump to

Keyboard shortcuts

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