cubapi

package
v0.4.5 Latest Latest
Warning

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

Go to latest
Published: Aug 29, 2026 License: MIT Imports: 33 Imported by: 2

Documentation

Overview

Entity provisioning (admin.go) holds idempotent create helpers for ConfigHub control-plane objects — Spaces, Triggers, Filters, and stored Invocations — plus wiring a Space's Triggers to a shared Filter. Each Ensure* helper creates the entity with allow-exists semantics, so it is safe to run repeatedly (the "install once per org" pattern), and returns the created or existing entity.

The helpers take the generated entity structs directly (goclientnew.Trigger, etc.) rather than re-describing them; fields the caller leaves unset (such as DisplayName) are defaulted by the server. Function arguments on Triggers and Invocations are built with Arguments.

Client construction (client.go) builds an authenticated ConfigHub API client for Go tools and `cub` plugins. It turns resolved credentials — a server URL plus a bearer token (or a full AuthSession for Basic auth) — into a ready *goclientnew.ClientWithResponses, and provides a server-verifying auth check.

Two credential sources are supported:

  • Plugin environment: the CUB_SERVER / CUB_TOKEN / CUB_SPACE variables that `cub` passes to plugins. Use NewClientFromEnvironment.
  • Local config: the active context of a Store (the ~/.confighub session a user creates with `cub auth login`). Use NewClientFromConfig.

ResolveClient tries the environment first and falls back to local config, so the same binary works both as a `cub` plugin and as a standalone CLI without code changes.

Config loading (config.go) is a kubeconfig-style loader for ConfigHub CLI configuration. It reads the on-disk format that `cub` writes — a config file (`~/.confighub/config.yaml`) holding named contexts, plus per-context token files (`~/.confighub/tokens/<name>.json`) — and resolves the active context and its credentials for use by other Go tools and `cub` plugins.

It is the analog of client-go's clientcmd: a reusable way to obtain "client info" (server URL, organization, default space, access token) without shelling out to `cub`. It has no dependency on cobra and holds no global state; construct a Store with LoadConfig and call methods on it.

This is the read/resolve half of `cub`'s ContextManager. Write operations (creating, renaming, and deleting contexts; persisting tokens) live with the `cub` CLI, which owns the login flow that produces them.

Config writing (config_write.go) is the mutation half of the kubeconfig-style Store: creating, renaming, and deleting contexts, persisting the config and token files, and first-run initialization. It complements the read/resolve methods in config.go. Friendly context-name generation is intentionally left to the caller (the cub CLI); Store.CreateContext takes an explicit name.

Mutations (mutate.go) are a dry-run/commit harness for ConfigHub data changes. It encodes one policy consistently:

  • An empty Change.Description means dry-run: the server previews the change and writes nothing.
  • A non-empty Description means commit: the change is written and the description is recorded with it.

It wraps the org-level function-invocation and bulk-patch endpoints and returns a structured Result (per-unit success, error, mutation diffs, and function outputs) instead of leaving callers to parse a CLI's text output.

Function arguments use the canonical api.FunctionArgument / api.FunctionInvocation types from core/function/api (with Evaluator constants api.EvaluatorTemplate / api.EvaluatorCEL); Arguments converts them to the generated client's form.

Queries (query.go) are typed, org-level read helpers over the ConfigHub API.

Two deliberate choices keep callers consistent:

  • Org-level endpoints only. Reads always use the cross-space "ListAll*" endpoints (and ListSpaces, which is already org-scoped), scoped with a Where clause. There is no per-space-vs-"*" branching to get wrong.
  • No globals. Every call takes an explicit Client and filter.

The generated list endpoints return "Extended" envelopes — e.g. ListAllUnits returns []ExtendedUnit, where the core record is in the .Unit field and related entities (.Space, .Target, …) are populated only when requested via ListOpts.Include.

Snapshots (snapshot.go) read a fleet-wide view of ConfigHub configuration: the units a filter selects, the resources inside them, and the unit / space / target metadata that says where each one lives.

It is the part of a fleet-wide tool that is not about any particular kind of configuration. A caller supplies the resource types it cares about and a function that turns one resource into its own model; everything between -- scoping, the two queries, the join, the cluster key -- is here.

Index

Constants

View Source
const (
	EntityTypeSpace        = "Space"
	EntityTypeFilter       = "Filter"
	EntityTypeView         = "View"
	EntityTypeInvocation   = "Invocation"
	EntityTypeTrigger      = "Trigger"
	EntityTypeTag          = "Tag"
	EntityTypeChangeSet    = "ChangeSet"
	EntityTypeChangeOrder  = "ChangeOrder"
	EntityTypeTarget       = "Target"
	EntityTypeBridgeWorker = "BridgeWorker"
	EntityTypeUnit         = "Unit"
	EntityTypeLink         = "Link"
	EntityTypeSet          = "Set"
	EntityTypeAttribute    = "Attribute"
	// Pseudo-EntityType
	EntityTypeInventory = "Inventory"
)

Entity types

View Source
const (
	// DefaultAssertionAudience must match the server's default. The audience
	// pins an assertion to one token endpoint, so a mismatch is a uniform 401
	// with nothing to distinguish it from a bad key. Deployments that set
	// CONFIGHUB_ASSERTION_AUDIENCE on the server must set it here too.
	DefaultAssertionAudience = "confighub-auth"

	// ClientAssertionTypeJWTBearer is fixed by RFC 7523 §2.2. The server
	// requires exactly this value.
	ClientAssertionTypeJWTBearer = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
)
View Source
const (
	// ConfigAPIVersion and ConfigKind identify the config file format. They
	// match the values `cub` writes.
	ConfigAPIVersion = "v1"
	ConfigKind       = "Config"

	// ConfigHubDir is the per-user ConfigHub directory under $HOME.
	ConfigHubDir = ".confighub"

	// ConfigFileName is the default config file name within ConfigHubDir.
	ConfigFileName = "config.yaml"
)
View Source
const (
	AuthTypeBasic = "Basic"
	AuthTypeJWT   = "JWT"
)
View Source
const ClusterNone = "None"

ClusterNone is the cluster key for units a snapshot cannot attribute to a cluster: their space has no release target, so there is nothing to name. They group under one bucket rather than each space standing in for a cluster of its own, which would count things that are not clusters.

View Source
const DefaultServerURL = "https://hub.confighub.com"

DefaultServerURL is the ConfigHub server used for a context when none is given.

View Source
const DefaultToolchainType = "Kubernetes/YAML"

DefaultToolchainType is used when a Selector leaves ToolchainType empty.

View Source
const DefaultUserAgent = "cub-sdk"

DefaultUserAgent is sent when ClientOptions.UserAgent is empty.

View Source
const MaxFilterLength = 8192

MaxFilterLength mirrors the server's cap on a filter expression. Going over it is rejected with a 400, not answered with a truncated result, so a clause that grows with the size of the fleet -- an IN over every unit in scope, say -- has to be optional: build it, measure the rendered filter, and drop it when it does not fit.

View Source
const ServerVersionHeader = "ConfigHub-Version"

ServerVersionHeader is the response header the ConfigHub server stamps its own version onto, on every /api response. A client that reads it learns the server version from a call it was already making, rather than spending a round trip on /api/info. The value is what /api/info reports in Version: a release version such as "v0.2.34", or "v0.2-dev" for a build from a working tree.

Variables

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

ErrEntityNotFound is used to mark entities that are not found during refresh

Functions

func Apply

func Apply(
	ctx context.Context,
	client *goclientnew.ClientWithResponses,
	data, lastAppliedData []byte,
	oldInventory *Inventory,
	defaultSpaceSlug string,
	unitSlug, spaceID string,
) ([]ApplyResult, *Inventory, error)

Apply processes the configuration data and returns the results and updated inventory. If unitSlug and spaceID are non-empty, each applied entity is annotated with the managing Unit's slug and SpaceID (confighub.com/UnitSlug, confighub.com/SpaceID), analogous to k8skit.EnsureConfigHubContextOnData for the Kubernetes bridge.

func Arguments added in v0.1.86

Arguments converts canonical function arguments into the generated FunctionArgument list, mirroring how the cub CLI builds them (positional vs named, optional evaluator, scalar value).

func CountTriggers added in v0.4.5

func CountTriggers(ctx context.Context, c *Client, spaceID goclientnew.UUID) (int, error)

CountTriggers returns how many triggers a space defines of its own.

func DefaultClusterKey added in v0.4.5

func DefaultClusterKey(meta UnitMeta) string

DefaultClusterKey names the cluster a unit's resources belong to: its target slug, or ClusterNone when its space has no release target.

func DefaultConfigPath added in v0.1.86

func DefaultConfigPath() (string, error)

DefaultConfigPath returns the config file path to use when none is given: config.yaml inside $CUB_CONFIG if set, otherwise $HOME/.confighub/config.yaml.

CUB_CONFIG names the config *directory*, not the file. That is what the published documentation says, what cub exports to plugins (`CUB_CONFIG=<dir>` in cmd/cub/plugin_exec.go), and what plugins already assume -- cub-che's installer builds "$CUB_CONFIG/plugins" from it. Returning the value verbatim treated it as the file, which put the sibling "tokens" and "keys" directories one level too high and split the store in two.

func EnsureFilter added in v0.1.86

func EnsureFilter(ctx context.Context, c *Client, filter goclientnew.Filter) (*goclientnew.Filter, error)

EnsureFilter idempotently creates a Filter in filter.SpaceID.

func EnsureInvocation added in v0.1.86

func EnsureInvocation(ctx context.Context, c *Client, invocation goclientnew.Invocation) (*goclientnew.Invocation, error)

EnsureInvocation idempotently creates a stored Invocation in invocation.SpaceID.

func EnsureSpace added in v0.1.86

func EnsureSpace(ctx context.Context, c *Client, space goclientnew.Space) (*goclientnew.Space, error)

EnsureSpace idempotently creates a Space and returns it (the existing Space if it already exists).

func EnsureTrigger added in v0.1.86

func EnsureTrigger(ctx context.Context, c *Client, trigger goclientnew.Trigger) (*goclientnew.Trigger, error)

EnsureTrigger idempotently creates a Trigger in trigger.SpaceID.

func FunctionInvocations added in v0.2.20

func FunctionInvocations(invocations ...api.FunctionInvocation) *goclientnew.FunctionInvocationList

FunctionInvocations converts canonical function invocations into the generated FunctionInvocationList, for the fields that hold one -- notably an Invocation's FunctionInvocations, which names the functions it calls in the order they execute.

func GetComponentListURL added in v0.2.5

func GetComponentListURL(serverURL string) string

GetComponentListURL returns the web UI URL for the component view with no component selected, i.e. the component overview.

func GetComponentURL added in v0.2.5

func GetComponentURL(serverURL, component, spaceID string) string

GetComponentURL returns the web UI URL for a specific component. The component is identified by the value of the well-known "Component" Space label, not by an entity ID: a component is the set of spaces sharing that label.

When spaceID is non-empty the UI additionally preselects that space's node in the component's deployment graph.

func GetEntityBySlug

func GetEntityBySlug(ctx context.Context, client *goclientnew.ClientWithResponses, entityType, slug, spaceID string) (interface{}, error)

GetEntityBySlug fetches an entity by its slug, similar to the old apiGet* functions but using direct client library calls without global variable dependencies

func GetRevisionByNum

func GetRevisionByNum(ctx context.Context, client *goclientnew.ClientWithResponses, spaceID, unitID string, revisionNum int64) (*goclientnew.ExtendedRevision, error)

GetRevisionByNum fetches a revision by its RevisionNum for a specific unit

func GetSpaceDetailURL

func GetSpaceDetailURL(serverURL, spaceID string) string

GetSpaceDetailURL returns the web UI URL for a specific space detail page

func GetSpaceListURL

func GetSpaceListURL(serverURL string) string

GetSpaceListURL returns the web UI URL for the spaces list page

func GetTargetListURL

func GetTargetListURL(serverURL string) string

GetTargetListURL returns the web UI URL for the targets list page

func GetUnitDetailURL

func GetUnitDetailURL(serverURL, spaceID, unitID string) string

GetUnitDetailURL returns the web UI URL for a specific unit detail page

func GetUnitEditURL

func GetUnitEditURL(serverURL, spaceID, unitID string) string

GetUnitEditURL returns the web UI URL for unit edit view Tab 1 is the edit tab in the unit detail page

func GetUnitListURL

func GetUnitListURL(serverURL string) string

GetUnitListURL returns the web UI URL for the units list page Note: Space context is handled by the UI session

func GetUnitRevisionsURL

func GetUnitRevisionsURL(serverURL, spaceID, unitID string) string

GetUnitRevisionsURL returns the web UI URL for unit revisions view Tab 2 is the revisions tab in the unit detail page

func GetWorkerListURL

func GetWorkerListURL(serverURL string) string

GetWorkerListURL returns the web UI URL for the bridge workers list page

func InterpretErrorGeneric

func InterpretErrorGeneric(err error, resp interface{}) error

InterpretErrorGeneric checks the response for any errors and returns an error if found. If we found no non-nil JSON4xx or JSON5xx, presumably it is a 2xx success or client initiated termination.

func InvocationFunctionNames added in v0.2.20

func InvocationFunctionNames(invocation *goclientnew.Invocation) []string

InvocationFunctionNames names the functions an Invocation calls, in the order it executes them. An Invocation usually calls one function, in which case this is just its name.

func IsAPIError

func IsAPIError(err error, resp APIResponse) bool

func IsCanonicalSpace added in v0.4.5

func IsCanonicalSpace(labels map[string]string) bool

IsCanonicalSpace reports whether a space holds definitions rather than deployed configuration. The standard Variant=base label marks a base or template space; a `role` label of base or policy is treated the same way.

func IsNotFoundError

func IsNotFoundError(err error) bool

IsNotFoundError returns true if the error represents a 404 Not Found response or a "not found" error from a slug lookup.

func ListAttributes added in v0.1.86

func ListAttributes(ctx context.Context, c *Client, where Where, opts ListOpts) ([]*goclientnew.ExtendedAttribute, error)

ListAttributes returns attributes across the organization matching where.

func ListBridgeWorkers added in v0.1.86

func ListBridgeWorkers(ctx context.Context, c *Client, where Where, opts ListOpts, with ...func(*goclientnew.ListAllBridgeWorkersParams)) ([]*goclientnew.ExtendedBridgeWorker, error)

ListBridgeWorkers returns bridge workers across the organization matching where. Bridge-worker-specific options (Summary) are set via the with mutators, which run after the common where/opts are applied.

func ListChangeOrders added in v0.2.13

func ListChangeOrders(ctx context.Context, c *Client, where Where, opts ListOpts) ([]*goclientnew.ExtendedChangeOrder, error)

ListChangeOrders returns change orders across the organization matching where.

func ListChangeSets added in v0.1.86

func ListChangeSets(ctx context.Context, c *Client, where Where, opts ListOpts) ([]*goclientnew.ExtendedChangeSet, error)

ListChangeSets returns change sets across the organization matching where.

func ListFilters added in v0.1.86

func ListFilters(ctx context.Context, c *Client, where Where, opts ListOpts, with ...func(*goclientnew.ListAllFiltersParams)) ([]*goclientnew.ExtendedFilter, error)

ListFilters returns filters across the organization matching where. Filter- specific options (Entity/Id) are set via the with mutators, which run after the common where/opts are applied.

func ListInvocations added in v0.1.86

func ListInvocations(ctx context.Context, c *Client, where Where, opts ListOpts) ([]*goclientnew.ExtendedInvocation, error)

ListInvocations returns stored invocations across the organization matching where.

func ListLinks(ctx context.Context, c *Client, where Where, opts ListOpts) ([]*goclientnew.ExtendedLink, error)

ListLinks returns links across the organization matching where. Links have no per-space "ListAll" endpoint; the org-level search endpoint is used.

func ListMarkedUnits added in v0.4.5

func ListMarkedUnits(ctx context.Context, c *Client, toolchain string) ([]*goclientnew.ExtendedUnit, error)

ListMarkedUnits returns the units a trigger has marked -- ApplyWarnings from an advisory rule, ApplyGates from a blocking one -- for the given toolchain type, deduplicated. Pass an empty toolchain for every toolchain.

It takes two queries because a `where` expression is a flat conjunction: there is no way to spell "has warnings OR has gates" in one.

func ListResources added in v0.2.8

func ListResources(ctx context.Context, c *Client, where Where, opts ListOpts, with ...func(*goclientnew.ListAllResourcesParams)) ([]*goclientnew.ExtendedResource, error)

ListResources returns the resources of units across the organization matching where. Resources are derived from unit configuration data and are read-only; there is no per-space "ListAll" endpoint, so the org-level search endpoint is used. Resource-specific options (RawData) are set via the with mutators, which run after the common where/opts are applied.

func ListSpaces added in v0.1.86

func ListSpaces(ctx context.Context, c *Client, where Where, opts ListOpts, with ...func(*goclientnew.ListSpacesParams)) ([]*goclientnew.ExtendedSpace, error)

ListSpaces returns spaces across the organization matching where. ListSpaces is already org-scoped, so there is no "ListAll" variant. Space-specific options (Summary) are set via the with mutators, which run after the common where/opts are applied.

func ListTags added in v0.1.86

func ListTags(ctx context.Context, c *Client, where Where, opts ListOpts) ([]*goclientnew.ExtendedTag, error)

ListTags returns tags across the organization matching where.

func ListTargets added in v0.1.86

func ListTargets(ctx context.Context, c *Client, where Where, opts ListOpts) ([]*goclientnew.ExtendedTarget, error)

ListTargets returns targets across the organization matching where.

func ListTriggers added in v0.1.86

func ListTriggers(ctx context.Context, c *Client, where Where, opts ListOpts) ([]*goclientnew.ExtendedTrigger, error)

ListTriggers returns triggers across the organization matching where.

func ListUnits added in v0.1.86

func ListUnits(ctx context.Context, c *Client, where Where, opts ListOpts, with ...func(*goclientnew.ListAllUnitsParams)) ([]*goclientnew.ExtendedUnit, error)

ListUnits returns units across the organization matching where, using the org-level ListAllUnits endpoint. Results are ExtendedUnit envelopes; the core record is in each element's .Unit field. Unit-specific options (ResourceType, WhereData, WhereTrigger, TriggerFilter, TriggersPassed, View) are set via the with mutators, which run after the common where/opts are applied.

func ListViews added in v0.1.86

func ListViews(ctx context.Context, c *Client, where Where, opts ListOpts) ([]*goclientnew.ExtendedView, error)

ListViews returns views across the organization matching where.

func MarshalYAMLWithoutReadonlyFields

func MarshalYAMLWithoutReadonlyFields(entityType string, entity interface{}, spaceSlug string) ([]byte, error)

MarshalYAMLWithoutReadonlyFields marshals an entity to YAML while excluding readonly fields. It uses the Patch types which contain only the mutable fields that should be included in LiveState. It also removes null fields, the Version field, and adds SpaceSlug for space-resident entities.

func Refresh

func Refresh(
	ctx context.Context,
	client *goclientnew.ClientWithResponses,
	currentData []byte,
	oldInventory *Inventory,
	defaultSpaceSlug string,
	liveRevisionNum int64,
	spaceID, unitID string,
) ([]ApplyResult, *Inventory, []byte, error)

Refresh gets the current state of entities in the inventory and updates the config data, inventory, and live state. It returns the same ApplyResult structure as Apply, along with updated inventory and refreshed config data.

func ResolveFilter added in v0.1.86

func ResolveFilter(ctx context.Context, c *Client, spaceID goclientnew.UUID, slug string) (*goclientnew.Filter, error)

ResolveFilter finds a single Filter by slug within a space.

func ResolveInvocation added in v0.1.86

func ResolveInvocation(ctx context.Context, c *Client, spaceID goclientnew.UUID, slug string) (*goclientnew.Invocation, error)

ResolveInvocation finds a single stored Invocation by slug within a space.

func ResolveSpace added in v0.1.86

func ResolveSpace(ctx context.Context, c *Client, slug string) (*goclientnew.Space, error)

ResolveSpace looks up a single space by slug and returns its core record. It errors if no space (or more than one) matches.

func SameServer added in v0.4.1

func SameServer(a, b string) bool

SameServer reports whether two URLs name the same ConfigHub.

A trailing slash and the case of the scheme or host do not make a different server, but a string comparison says they do -- which splits one instance across two contexts, so a login updates one and a later command reads the other. Anything it cannot parse is compared as written.

func SelectFields added in v0.1.86

func SelectFields(value string) string

SelectFields normalizes a select value for use in ListOpts.Select: the "*" wildcard (meaning "all fields") becomes "", which the API treats the same way and which the list helpers omit from the request. Callers translating a CLI --select value should pass it through this.

func SetSpaceTriggerFilter added in v0.1.86

func SetSpaceTriggerFilter(ctx context.Context, c *Client, space *goclientnew.Space, filterID goclientnew.UUID) error

SetSpaceTriggerFilter points a Space's Triggers at a shared Filter: it sets the Space's TriggerFilterID to filterID and clears its WhereTrigger. space should be a full Space record (e.g. from ResolveSpace).

func SpaceSlugByID added in v0.1.86

func SpaceSlugByID(ctx context.Context, c *Client) (map[goclientnew.UUID]string, error)

SpaceSlugByID returns a map from space UUID to slug for the whole organization, for resolving the SpaceID fields on units and other entities.

func SpacesWithToolchain added in v0.4.5

func SpacesWithToolchain(ctx context.Context, c *Client, toolchain string) (map[string]bool, error)

SpacesWithToolchain returns the slugs of the spaces holding at least one unit of the given toolchain type. It answers "where is there configuration of this kind at all", which is what keeps a fleet-wide install from wiring a space whose contents the tool has nothing to say about.

func WithOrganization added in v0.2.5

func WithOrganization(webURL, externalOrgID string) string

WithOrganization adds the "org" query parameter to a web UI URL, naming the organization the URL should be viewed in. Without it the UI renders whichever organization the browser session last selected, which for anyone in more than one org silently shows the wrong data — or nothing at all, since the spaces and units in the path belong to a different org.

externalOrgID must be the organization's ExternalID (the identity provider's ID), not its ConfigHub OrganizationID: the UI compares it against the current session's external org ID and hands it to /auth/switch-organization, which verifies membership against the identity provider. An empty externalOrgID, or a URL that already names an org, is left alone.

Types

type APIResponse

type APIResponse interface {
	StatusCode() int
}

type ApplyResult

type ApplyResult struct {
	EntityType string
	EntityName string
	EntityID   string
	SpaceSlug  string
	Action     string // "created", "updated", "deleted", "failed"
	Error      error
	Entity     interface{} // Store the created/updated entity for display
}

func Destroy

func Destroy(ctx context.Context, client *goclientnew.ClientWithResponses, inventory *Inventory, defaultSpaceSlug string) []ApplyResult

type AssertionSigner added in v0.2.32

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

AssertionSigner signs private_key_jwt assertions for one identity.

func NewAssertionSigner added in v0.2.32

func NewAssertionSigner(privateJWK []byte, subject, audience string) (*AssertionSigner, error)

NewAssertionSigner builds a signer from a private JWK.

subject may be empty when the JWK records the holder's external id, which is what `cub user key add --generate` writes. An explicit subject wins, so a key generated elsewhere can still be used by naming the identity separately.

audience may be empty for DefaultAssertionAudience.

func (*AssertionSigner) Kid added in v0.2.32

func (s *AssertionSigner) Kid() string

Kid is the thumbprint the server will look the key up by.

func (*AssertionSigner) Sign added in v0.2.32

func (s *AssertionSigner) Sign() (string, error)

Sign produces a assertion valid from now.

iss and sub both carry the identity: RFC 7523 §3 requires both, and for client authentication the client is its own subject. The server checks that they match the identity that owns the key, so an assertion signed with a real key cannot claim to be about somebody else.

func (*AssertionSigner) Subject added in v0.4.0

func (s *AssertionSigner) Subject() string

UserID is the identity this signer authenticates as.

type AuthSession

type AuthSession struct {
	User           User   `json:"user"`
	AccessToken    string `json:"access_token"`
	RefreshToken   string `json:"refresh_token,omitempty"`
	OrganizationID string `json:"organization_id"`
	AuthType       string `json:"auth_type"`

	// Note: This field is not part of the API. We just use it to pass the password to setAuthHeaderToken.
	BasicAuthPassword string `json:"basic_auth_password,omitempty"`
}

func PerformAssertionAuth added in v0.2.32

func PerformAssertionAuth(serverURL string, signer *AssertionSigner) (*AuthSession, error)

PerformAssertionAuth authenticates by signing a short-lived assertion and exchanging it for a session, the asymmetric counterpart to PerformWorkerAuth.

Nothing secret crosses the wire: the assertion is a signature over claims the server can verify with the public key it already holds, and it expires in minutes. That is the whole point of the exchange -- PerformWorkerAuth sends a credential ConfigHub stored and can replay, this one sends proof of a credential ConfigHub has never seen.

The identity is carried inside the assertion (its iss and sub, and the kid in its header), so unlike PerformWorkerAuth nothing else needs naming here. The server resolves the credential from the kid alone.

func PerformWorkerAuth

func PerformWorkerAuth(serverURL, workerID, workerSecret string) (*AuthSession, error)

type Change added in v0.1.86

type Change struct {
	// Description is recorded with the change on commit. Empty means dry-run.
	Description string
}

Change describes whether a mutation is a dry-run preview or a commit. The zero value is a dry-run.

func (Change) DryRun added in v0.1.86

func (ch Change) DryRun() bool

DryRun reports whether this is a preview (no Description).

type Client added in v0.1.86

type Client struct {
	API    *goclientnew.ClientWithResponses
	Server string // server URL without the "/api" suffix
	Space  string // default space slug, if known
	// contains filtered or unexported fields
}

Client wraps the generated API client together with the resolved server URL and default space, so tools don't have to thread them separately.

func NewClient added in v0.1.86

func NewClient(opts ClientOptions) (*Client, error)

NewClient constructs a Client from explicit options. It returns an error if ServerURL is empty.

func NewClientFromConfig added in v0.1.86

func NewClientFromConfig(ctx context.Context, store *Store, opts ClientOptions) (*Client, error)

NewClientFromConfig builds a Client from a Store's active context, loading the bearer token from the context's token file. The context's default space becomes the client's default space unless opts.Space is already set.

func NewClientFromEnvironment added in v0.1.86

func NewClientFromEnvironment(ctx context.Context, opts ClientOptions) (*Client, error)

NewClientFromEnvironment builds a Client from the CUB_SERVER / CUB_TOKEN / CUB_SPACE variables (plugin mode). Fields set on opts (UserAgent, Debug, HTTPClient) are honored; opts.ServerURL/Token/Space are overridden by the environment. It returns an error when the environment lacks credentials.

func ResolveClient added in v0.1.86

func ResolveClient(ctx context.Context, opts ClientOptions) (*Client, error)

ResolveClient builds a Client using whichever credential source is available, preferring the plugin environment (CUB_SERVER/CUB_TOKEN) and falling back to the local ~/.confighub config (honoring CUB_CONFIG / CUB_CONTEXT). This is the one-call entry point for tools that should work both as a `cub` plugin and as a standalone CLI.

func (*Client) ServerVersion added in v0.3.0

func (c *Client) ServerVersion() string

ServerVersion returns the version the server reported on the most recent response, or "" if no request has completed yet or the server does not stamp ServerVersionHeader (a server older than the header). Callers that need the version regardless can fall back to /api/info.

func (*Client) VerifyAuth added in v0.1.86

func (c *Client) VerifyAuth(ctx context.Context) (*goclientnew.OrganizationMember, error)

VerifyAuth round-trips GET /me to confirm the credentials are accepted by the server. It is the direct-API equivalent of `cub auth status`: unlike a local token check, it proves the server honors the token right now. On success it returns the authenticated organization member.

type ClientOptions added in v0.1.86

type ClientOptions struct {
	ServerURL string
	Token     string
	Session   *AuthSession

	// Space is the default space slug, when known (e.g. from CUB_SPACE or the
	// active context's settings). It is carried on the returned Client for
	// callers' convenience and does not affect requests.
	Space string

	UserAgent  string
	Debug      bool         // dump requests and responses to stdout
	HTTPClient *http.Client // base client; defaults to a client using http.DefaultTransport
}

ClientOptions configures client construction. ServerURL is required; the rest are optional. Provide either Token (bearer) or Session (which additionally supports Basic auth); Session takes precedence when both are set.

type Config added in v0.1.86

type Config struct {
	APIVersion     string     `yaml:"apiVersion" json:"apiVersion"`
	Kind           string     `yaml:"kind" json:"kind"`
	CurrentContext string     `yaml:"currentContext,omitempty" json:"currentContext,omitempty"`
	Contexts       []*Context `yaml:"contexts" json:"contexts"`
}

Config is the root of the config file: a kubeconfig-like document with a list of named contexts and a pointer to the current one.

type Context added in v0.1.86

type Context struct {
	Name       string     `yaml:"name" json:"name"`
	Coordinate Coordinate `yaml:"coordinate" json:"coordinate"`
	Settings   Settings   `yaml:"settings" json:"settings"`
	Metadata   Metadata   `yaml:"metadata" json:"metadata"`
}

Context is a named configuration: a coordinate identifying the server, a few settings, and metadata including which token file holds its credentials.

type Coordinate added in v0.1.86

type Coordinate struct {
	ServerURL      string `yaml:"serverURL" json:"serverURL"`
	OrganizationID string `yaml:"organizationID" json:"organizationID"`
	User           string `yaml:"user" json:"user"`
}

Coordinate uniquely identifies a context: server URL, organization, and user.

func (Coordinate) Equals added in v0.1.86

func (c Coordinate) Equals(other Coordinate) bool

Equals reports whether two coordinates identify the same context.

type Environment added in v0.1.86

type Environment struct {
	Server  string `env:"CUB_SERVER"`
	Token   string `env:"CUB_TOKEN"`
	Space   string `env:"CUB_SPACE"`
	Config  string `env:"CUB_CONFIG"`
	Context string `env:"CUB_CONTEXT"`
}

Environment holds the credentials `cub` passes to plugins via environment variables (see core/plugin and cub's plugin execution). It is populated with go-envconfig.

func LoadEnvironment added in v0.1.86

func LoadEnvironment(ctx context.Context) (Environment, error)

LoadEnvironment reads the CUB_* variables from the process environment.

func (Environment) HasCredentials added in v0.1.86

func (e Environment) HasCredentials() bool

HasCredentials reports whether the environment carries enough to build a client directly (server URL and token), i.e. the binary is running as a `cub` plugin.

type Inventory

type Inventory struct {
	EntityType string              `yaml:"EntityType"`
	Resources  []InventoryResource `yaml:"Resources"`
}

type InventoryResource

type InventoryResource struct {
	ResourceType string `yaml:"ResourceType"`
	ResourceName string `yaml:"ResourceName"`
}

type ListOpts added in v0.1.86

type ListOpts struct {
	// Select is a comma-separated, PascalCase list of fields to return.
	Select string
	// Include expands related entities into the Extended envelope (e.g.
	// "SpaceID,TargetID" to populate .Space and .Target on a unit).
	Include string
	// Filter names a stored Filter to apply, as "space/filter" or "filter".
	Filter string
	// Contains is a free-text search.
	Contains string
}

ListOpts carries the query parameters common to every list helper. Zero values are omitted from the request. Entity-specific parameters are set via each helper's mutator functions.

type MemoizedClient added in v0.4.5

type MemoizedClient struct {
	// UserAgent identifies the tool to the server, e.g. "cub-netpol". Empty uses
	// [DefaultUserAgent].
	UserAgent string
	// contains filtered or unexported fields
}

MemoizedClient is one tool's connection to ConfigHub, built on first use by ResolveClient -- from the cub plugin environment (CUB_SERVER / CUB_TOKEN) or the local ~/.confighub session -- and reused thereafter.

The zero value is usable; set UserAgent so the server can tell tools apart. A MemoizedClient must not be copied after first use.

func (*MemoizedClient) Client added in v0.4.5

func (m *MemoizedClient) Client(ctx context.Context) (*Client, error)

Client returns the memoized client. Building it performs no network I/O; use MemoizedClient.Preflight to verify the session against the server.

func (*MemoizedClient) Preflight added in v0.4.5

func (m *MemoizedClient) Preflight(ctx context.Context) (*Client, error)

Preflight is the standard gate for any ConfigHub-touching command: it builds the client and verifies the session against the server, rather than only reading local state, so an expired token is reported here instead of surfacing as an unrelated failure further in. It returns the ready client, or an error carrying the remediation.

type Metadata added in v0.1.86

type Metadata struct {
	TokenFile string `yaml:"tokenFile" json:"tokenFile"`

	// PrivateKey names the key this context authenticates with, in the form it
	// was given: an alias in the key directory, a path, or empty for a context
	// that authenticates some other way.
	//
	// It is a reference, never key material. Recording it is what lets a session
	// be renewed without being told again which key to use -- with a credential
	// that needs no human, an expired token is a detail the caller should not
	// have to handle.
	PrivateKey string `yaml:"privateKey,omitempty" json:"privateKey,omitempty"`

	OrganizationName string    `yaml:"organizationName,omitempty" json:"organizationName,omitempty"`
	Created          time.Time `yaml:"created,omitempty" json:"created,omitempty"`
	LastUsed         time.Time `yaml:"lastUsed,omitempty" json:"lastUsed,omitempty"`
	Description      string    `yaml:"description,omitempty" json:"description,omitempty"`
}

Metadata holds optional, non-identifying context data.

type Origin added in v0.4.5

type Origin struct {
	// Cluster is the key resources are grouped by, [ClusterNone] when the unit's
	// space has no release target.
	Cluster string
	// Target is the unit's target slug, empty when it has none.
	Target       string
	Space        string
	SpaceID      string
	SpaceLabels  map[string]string
	UnitID       string
	UnitSlug     string
	ResourceName string
	ResourceType string
	// Canonical marks a definition in a base or policy space: shown in
	// inventories, kept out of cluster analysis.
	Canonical bool
}

Origin is where one resource came from: the ConfigHub entities that hold it and the cluster a snapshot attributes it to.

type Result added in v0.1.86

type Result struct {
	DryRun   bool
	Outcomes []UnitOutcome
}

Result aggregates the per-unit outcomes of a mutation.

func InvokeFunction added in v0.1.86

func InvokeFunction(ctx context.Context, c *Client, fn api.FunctionInvocation, sel Selector, ch Change) (*Result, error)

InvokeFunction runs an ad-hoc function over the units matching sel, as a dry-run preview or a commit per ch. It also serves read-only functions (e.g. get-resources): inspect UnitOutcome.Outputs on the result.

func InvokeStoredInvocation added in v0.1.86

func InvokeStoredInvocation(ctx context.Context, c *Client, invocationID goclientnew.UUID, params map[string]any, sel Selector, ch Change) (*Result, error)

InvokeStoredInvocation runs a parameterized stored Invocation (by ID) over the units matching sel, as a dry-run preview or a commit per ch.

func UpgradeUnits added in v0.1.86

func UpgradeUnits(ctx context.Context, c *Client, where string, ch Change) (*Result, error)

UpgradeUnits performs a bulk "--upgrade" patch over the units matching where: each unit is reconciled with its upstream. It is a dry-run preview or a commit per ch.

func (*Result) Failed added in v0.1.86

func (r *Result) Failed() []UnitOutcome

Failed returns the outcomes that did not succeed.

type Selector added in v0.1.86

type Selector struct {
	Where         string // unit filter, e.g. "Slug = 'checkout'" or "SpaceID = '...'"
	WhereData     string // filter on config data
	WhereResource string // filter on resources within the config data
	ResourceType  string // e.g. "apps/v1/Deployment"
	ToolchainType string // defaults to DefaultToolchainType
	ExecutorSpace string // optional space whose worker/context executes functions
}

Selector scopes a mutation to a set of units using the org-level endpoints. Where is required for org-wide invocation and bulk patch.

type Settings added in v0.1.86

type Settings struct {
	DefaultSpace string `yaml:"defaultSpace" json:"defaultSpace"`
}

Settings holds per-context preferences.

type Snapshot added in v0.4.5

type Snapshot[R any] struct {
	// Resources is every resource that was read, canonical ones included.
	Resources []R
	// Units is in-scope unit metadata by UnitID.
	Units map[string]UnitMeta
	// Filter is the unit `where` predicate the snapshot was scoped by; empty
	// means the whole fleet the caller can view.
	Filter string `json:"filter,omitempty"`
}

Snapshot is one fleet-wide read: every resource a caller asked for, and the metadata of every unit in scope.

type SnapshotLoader added in v0.4.5

type SnapshotLoader[R any] struct {
	// ResourceTypes are the exact ResourceTypes to read, e.g.
	// "apps/v1/Deployment". They become one IN clause, which is how a union of
	// values is written in a filter language that has no OR. Naming versions
	// exactly means a new API version has to be added here.
	ResourceTypes []string

	// ResourceWhere replaces ResourceTypes with a raw clause, for a set that
	// cannot be enumerated -- an API group whose kinds are open-ended, say.
	// Prefer ResourceTypes: an exact list needs no pattern and no re-matching.
	ResourceWhere string

	// Toolchain scopes both queries to one toolchain type, e.g.
	// "Kubernetes/YAML". Defaults to [DefaultToolchainType].
	//
	// It is a field rather than a clause in UnitWhere because ToolchainType is a
	// column on the resource as well as on the unit, so naming it once puts the
	// term in both queries, where each is narrowed by it in SQL.
	Toolchain string

	// UnitWhere further scopes which units are in scope at all, ANDed with the
	// caller's predicate. Empty means the toolchain alone decides.
	UnitWhere string

	// ClusterKey names the cluster a unit's resources belong to. Defaults to
	// [DefaultClusterKey]. Override it where the cluster a caller reports is not
	// the target the configuration is delivered to.
	ClusterKey func(UnitMeta) string

	// Canonical reports whether a space holds definitions rather than deployed
	// configuration. Defaults to [IsCanonicalSpace].
	Canonical func(spaceLabels map[string]string) bool

	// Keep, when set, decides whether a resource that came back is kept. Use it
	// where ResourceWhere is broader than the set actually wanted: a filter
	// literal cannot carry a backslash, so a pattern's dots match any character
	// and the clause can only be written broader than intended, never narrower.
	Keep func(Origin) bool

	// New builds the caller's own resource from its origin and its
	// configuration, which arrives as already-parsed JSON. It is called once per
	// resource read, in the order the query returned them.
	New func(Origin, map[string]any) R
}

SnapshotLoader reads a fleet snapshot. The zero value is not usable: New is required, and so is one of ResourceTypes or ResourceWhere.

func (SnapshotLoader[R]) Load added in v0.4.5

func (l SnapshotLoader[R]) Load(ctx context.Context, c *Client, where string) (*Snapshot[R], error)

Load reads the snapshot, scoped by a single ConfigHub unit `where` predicate; empty means everything the caller can view. The predicate may reference unit, space and target metadata, and the server applies it.

Where it applies it is worth knowing when a scope can be written more than one way. A term naming the unit's own columns -- Slug, Labels, ToolchainType, SpaceID -- is compiled into the SQL query. A term prefixed with another entity -- Space.Labels.Environment, Target.ProviderType -- cannot be, so the server expands that entity for every row the SQL query returned and evaluates the term afterwards. Both answer the same question; only the first narrows the read. Prefer a unit-level term where the caller has the choice.

type Store added in v0.1.86

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

Store loads and resolves ConfigHub CLI configuration from a config file plus a sibling token directory. Use [Load] to construct one. Methods are safe for concurrent use.

Unlike `cub`'s ContextManager, a Store is read-only and never panics: a missing config file yields an empty but usable Store (no contexts), and resolving the active context returns an error rather than panicking when none is set.

func LoadConfig added in v0.1.86

func LoadConfig(path string) (*Store, error)

LoadConfig reads the config at path and returns a Store. If path is empty, DefaultConfigPath is used. The token directory is the sibling "tokens" directory next to the config file.

A missing config file is not an error: the returned Store has no contexts. This lets callers fall back to other credential sources (e.g. plugin environment variables) without special-casing a first run.

func LoadOrInit added in v0.1.86

func LoadOrInit(path, defaultContextName string) (*Store, error)

LoadOrInit loads the config at path, or — when no config file exists yet — creates a fresh one with a single default context named defaultContextName (server and space defaulted), makes it current, and persists it. It is the first-run initialization a CLI runs on startup. If path is empty, DefaultConfigPath is used.

func (*Store) ActiveContext added in v0.1.86

func (s *Store) ActiveContext() (*Context, error)

ActiveContext returns the context to use: the [Use] override if set, otherwise the current context from the config file. It returns an error when no context is configured.

func (*Store) ConfigPath added in v0.1.86

func (s *Store) ConfigPath() string

ConfigPath returns the absolute path of the loaded config file.

func (*Store) Context added in v0.1.86

func (s *Store) Context(name string) (*Context, error)

Context returns the context with the given name.

func (*Store) Contexts added in v0.1.86

func (s *Store) Contexts() []*Context

Contexts returns all configured contexts.

func (*Store) CreateContext added in v0.1.86

func (s *Store) CreateContext(name, serverURL, organization, defaultSpace string) (*Context, error)

CreateContext adds a new context with the given (required, valid, unique) name. serverURL, organization, and defaultSpace fall back to defaults when empty. The first context created becomes the current one. It mutates the in-memory config only; call Store.SaveConfig to persist.

func (*Store) CurrentContextName added in v0.1.86

func (s *Store) CurrentContextName() string

CurrentContextName returns the name of the current context as recorded in the config file (ignoring any in-memory override). It is empty when no context is configured.

func (*Store) DeleteContext added in v0.1.86

func (s *Store) DeleteContext(name string) error

DeleteContext removes a context (and its token file) and persists the config. The last remaining context cannot be deleted; deleting the current context switches to another.

func (*Store) DeleteTokenData added in v0.1.86

func (s *Store) DeleteTokenData(ctx *Context) error

DeleteTokenData removes a context's token file (a missing file is not an error).

func (*Store) FindContextByCoordinate added in v0.1.86

func (s *Store) FindContextByCoordinate(coordinate Coordinate) (*Context, error)

FindContextByCoordinate returns the context whose coordinate matches.

func (*Store) GetAllContextNames added in v0.1.86

func (s *Store) GetAllContextNames() []string

GetAllContextNames returns the names of all configured contexts.

func (*Store) KeyDir added in v0.2.32

func (s *Store) KeyDir() string

KeyDir is the directory bare key aliases resolve within.

func (*Store) KeyPath added in v0.2.32

func (s *Store) KeyPath(key string) string

KeyPath resolves a private-key reference to an absolute path, by the same three rules as TokenPath: absolute paths are used as-is, "~"-prefixed paths expand against $HOME, and a bare name is an *alias* resolving within the Store's key directory.

An alias gains the ".jwk" suffix when it has no extension, so `--private-key ci` and `--private-key ci.jwk` name the same key. Only a bare name is treated as an alias; anything containing a separator is a path, so "./ci" is a file in the working directory and never a lookup in the key directory.

func (*Store) RenameContext added in v0.1.86

func (s *Store) RenameContext(oldName, newName string) error

RenameContext renames a context, moving its token file and updating the current context if it was the one renamed. It mutates in-memory config (and the token file on disk) only; call Store.SaveConfig to persist the config.

func (*Store) SaveConfig added in v0.1.86

func (s *Store) SaveConfig() error

SaveConfig writes the configuration to the config file (creating the config directory if needed).

func (*Store) SaveTokenData added in v0.1.86

func (s *Store) SaveTokenData(ctx *Context, token *TokenData) error

SaveTokenData writes a context's credentials to its token file (creating the token directory with secure permissions if needed).

func (*Store) SetCurrentContext added in v0.1.86

func (s *Store) SetCurrentContext(name string) error

SetCurrentContext makes name the current context and stamps its LastUsed. It mutates in-memory config only; call Store.SaveConfig to persist.

func (*Store) TokenData added in v0.1.86

func (s *Store) TokenData(ctx *Context) (*TokenData, error)

TokenData loads the credentials for a context from its token file.

func (*Store) TokenPath added in v0.1.86

func (s *Store) TokenPath(tokenFile string) string

TokenPath resolves a context's token file to an absolute path, matching `cub`: absolute paths are used as-is, "~"-prefixed paths expand against $HOME, and bare names resolve within the Store's token directory.

func (*Store) Use added in v0.1.86

func (s *Store) Use(name string) error

Use sets an in-memory active-context override for the lifetime of this Store. It does not modify the config file. Passing "" clears the override.

func (*Store) WritePrivateKey added in v0.4.1

func (s *Store) WritePrivateKey(name string, privateJWK json.RawMessage) (string, error)

WritePrivateKey stores a private key in the key directory and returns where it went. name is resolved by KeyPath, so a bare alias becomes <keydir>/<name>.jwk and a path is honoured as given.

Refuses to overwrite: the file is frequently the only copy of a key whose public half is already registered, so replacing it would revoke a working credential irrecoverably. Anything else provisioning a key into this directory goes through here, so the permissions and that rule stay the same.

type TokenData added in v0.1.86

type TokenData struct {
	AccessToken  string `json:"accessToken"`
	RefreshToken string `json:"refreshToken,omitempty"`
}

TokenData is the contents of a token file.

type UnitMeta added in v0.4.5

type UnitMeta struct {
	UnitID                  string            `json:"unitId"`
	Slug                    string            `json:"slug"`
	SpaceID                 string            `json:"spaceId"`
	SpaceSlug               string            `json:"spaceSlug"`
	SpaceLabels             map[string]string `json:"spaceLabels,omitempty"`
	TargetID                string            `json:"targetId,omitempty"`
	TargetSlug              string            `json:"targetSlug,omitempty"`
	Labels                  map[string]string `json:"labels,omitempty"`
	GateCount               int               `json:"gateCount"`
	WarningCount            int               `json:"warningCount,omitempty"`
	HeadRevisionNum         int64             `json:"headRevisionNum"`
	LastReleasedRevisionNum int64             `json:"lastReleasedRevisionNum,omitempty"`
	UpstreamRevisionNum     int64             `json:"upstreamRevisionNum,omitempty"`
	LastChangeDescription   string            `json:"lastChangeDescription,omitempty"`
}

UnitMeta is the per-unit metadata a snapshot joins onto resources. It also stands on its own: a unit holding none of the resource types a caller asked for still appears here, which is what lets a fleet inventory count units the resource query cannot see.

func (UnitMeta) Gated added in v0.4.5

func (u UnitMeta) Gated() bool

Gated reports whether the unit has any ApplyGates attached.

func (UnitMeta) Unreleased added in v0.4.5

func (u UnitMeta) Unreleased() bool

Unreleased reports whether the unit's head revision has not been captured by a release. Publishing a release advances LastReleasedRevisionNum, so it is the field that answers "is what is authored here the thing that was published".

type UnitOutcome added in v0.1.86

type UnitOutcome struct {
	UnitID       string
	SpaceID      string
	SpaceSlug    string
	UnitSlug     string
	Success      bool
	Error        string
	HasMutations bool
	// Mutations carries the (old -> new) diffs for rendering, when present.
	Mutations *goclientnew.ResourceMutationList
	// Outputs holds function output types mapped to embedded-JSON output data
	// (e.g. the result of a read-only function like get-resources).
	Outputs map[string]string
}

UnitOutcome is the per-unit result of a mutation or function invocation.

type User

type User struct {
	ID                string            `json:"id"`
	Email             string            `json:"email"`
	FirstName         string            `json:"first_name"`
	LastName          string            `json:"last_name"`
	ProfilePictureURL string            `json:"profile_picture_url"`
	CreatedAt         string            `json:"created_at"`
	UpdatedAt         string            `json:"updated_at"`
	ExternalID        string            `json:"external_id,omitempty"`
	Metadata          map[string]string `json:"metadata,omitempty"`
}

type Where added in v0.1.86

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

Where builds a SQL-inspired filter expression by AND-ing clauses, matching the syntax the ConfigHub API accepts for its "where" parameters. The zero value is an empty (match-all) filter. Where is immutable; each method returns a new value.

It carries a deferred error, reported by Where.Err and returned by every list helper before a request is made, so that the builder stays chainable. The error comes from a value that cannot be expressed: see Where.Eq.

func NewWhere added in v0.1.86

func NewWhere(clause string) Where

NewWhere starts a filter from a raw clause. An empty clause yields an empty filter.

func (Where) And added in v0.1.86

func (w Where) And(clause string) Where

And appends a raw clause, AND-ed with the existing ones. An empty clause is ignored, so And is safe to call with optional predicates.

func (Where) Empty added in v0.1.86

func (w Where) Empty() bool

Empty reports whether the filter has no clauses.

func (Where) Eq added in v0.4.5

func (w Where) Eq(field, value string) Where

Eq appends a `<field> = '<value>'` predicate.

A value carrying a single quote or a backslash is rejected rather than escaped. The server screens every filter literal with an anchored regexp that admits neither, because it builds its SQL by concatenation with no parameter binding and that screen is what keeps the expression from being an injection point. So such a value is not merely awkward to send, it cannot be sent: the server answers a 400 at parse time. Nor is there an escape to reach for -- doubling the quote does not mean the character, it means a different value, and the query would silently answer a question the caller did not ask.

The error is deferred to Where.Err so that Eq stays chainable, and every list helper returns it before issuing a request, which turns a 400 naming a position in an expression the caller never wrote into an error naming the value.

func (Where) Err added in v0.4.5

func (w Where) Err() error

Err reports the first value that could not be expressed as a filter literal, nil when every clause is sendable.

func (Where) In added in v0.1.86

func (w Where) In(field string, ids []goclientnew.UUID) Where

In appends a `<field> IN ('a','b',…)` predicate over UUIDs. Calling In with no ids is a no-op (it returns the filter unchanged); callers that need "match nothing" semantics for an empty set should short-circuit before querying.

func (Where) InStrings added in v0.4.5

func (w Where) InStrings(field string, values []string) Where

InStrings appends a `<field> IN ('a','b',…)` predicate over string values, which is how a union is written in a filter language that has no OR. Calling it with no values is a no-op. A value that cannot appear in a filter literal is rejected the same way Where.Eq rejects one.

func (Where) Slug added in v0.1.86

func (w Where) Slug(slug string) Where

Slug appends a `Slug = '<slug>'` predicate.

func (Where) SpaceID added in v0.1.86

func (w Where) SpaceID(id goclientnew.UUID) Where

SpaceID appends a `SpaceID = '<id>'` predicate, scoping a query to one space while still using an org-level endpoint.

func (Where) String added in v0.1.86

func (w Where) String() string

String renders the filter as the API "where" expression.

Jump to

Keyboard shortcuts

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