Documentation
¶
Index ¶
- Constants
- Variables
- func RewriteImageForCluster(image, currentClusterID string, store RegistryStore) string
- func ValidateContainerImage(image string) error
- type APIKeyItem
- type APIKeyResult
- type APIKeyService
- type ClusterConfigSink
- type ClusterService
- type CreateAPIKeyInput
- type CreateKeyRequest
- type CreateKeyResponse
- type CreateSandboxEnvInput
- type CreateSandboxInput
- type CrossClusterForwarder
- type EnvRouter
- type EnvShellService
- type ExecTokenInfo
- type ExecTokenRecord
- type ExtProcClient
- type IAMResolveResult
- type IAMService
- type KeyMetadata
- type LastCreateBumper
- type ListSandboxesResult
- type OrganizationService
- type QuotaService
- type RegistryStore
- type RouteInfo
- type SandboxEnvService
- type SandboxListFilter
- type SandboxService
- type SandboxTemplateService
- type SyncHTTPError
- type SyncService
- type URLKind
- type UpdateSandboxEnvInput
Constants ¶
const ( // URLKindNative forwards to GatewayConfig.NativeAPIBaseURL. URLKindNative = cluster.URLKindNative // URLKindE2B forwards to GatewayConfig.E2BAPIBaseURL. URLKindE2B = cluster.URLKindE2B )
const MetaKeyScalingGroup = "agentbox.scitix.ai/scaling-group"
MetaKeyScalingGroup is the reserved create-metadata key that pins a sandbox to a specific autoscaling group (e.g. "1c2Gi"). Both the E2B-compatible and the native create handlers consume it into CreateSandboxInput.RequestedScalingGroup and strip it from the metadata that gets stored on the pod. Empty / absent = no group constraint (any member pool of the env is eligible — unchanged behaviour). The value is matched verbatim against a member's EnvClusterMemberConfig.ScalingGroup.
Variables ¶
var ErrSyncNotConnected = errors.New("ws-proxy sync not connected")
ErrSyncNotConnected is returned when an operation requires an active sync session to ws-proxy but none is established.
Functions ¶
func RewriteImageForCluster ¶ added in v0.0.2
func RewriteImageForCluster(image, currentClusterID string, store RegistryStore) string
RewriteImageForCluster rewrites the registry host of image when the image belongs to a private registry owned by a different cluster.
Rewrite rules:
- Parse the image reference to extract its registry host.
- Look up the host in the store. If not found → public registry, return as-is.
- If the owning cluster equals currentClusterID → already local, return as-is.
- Find a registry of the same Type in currentClusterID. If none found → warn and return as-is (never block the request).
- Replace the registry host prefix and return the rewritten image.
func ValidateContainerImage ¶
ValidateContainerImage is a thin alias kept so service-package callers can stay against the existing symbol; the implementation lives in pkg/sandboxrender so the controller layer can validate without taking a service-package dependency.
Types ¶
type APIKeyItem ¶ added in v0.0.5
type APIKeyItem struct {
KeyMetadata
// ShortName is the Kubernetes Secret name (without namespace prefix).
ShortName string
}
APIKeyItem holds the displayable metadata for a single API key (no token).
type APIKeyResult ¶ added in v0.0.5
type APIKeyResult struct {
RawToken string // shown once only
KeyMetadata
}
APIKeyResult is the result of a successful Create operation. RawToken is the opaque token and is returned only on creation.
type APIKeyService ¶
type APIKeyService interface {
Create(ctx context.Context, input CreateAPIKeyInput) (*APIKeyResult, *domain.AppError)
List(ctx context.Context) ([]APIKeyItem, *domain.AppError)
ListByTeamAndUser(ctx context.Context, team, user string) ([]APIKeyItem, *domain.AppError)
Get(ctx context.Context, keyID string) (*APIKeyItem, *domain.AppError)
Delete(ctx context.Context, keyID string) *domain.AppError
// Promote elevates a locally-created key to a global key by syncing it
// through the ws-proxy manager to all Worker clusters.
Promote(ctx context.Context, keyID string) *domain.AppError
}
APIKeyService defines business operations for API key management.
func NewAPIKeyService ¶
func NewAPIKeyService(store apikey.KeyStore) APIKeyService
NewAPIKeyService creates a new APIKeyService backed by the provided KeyStore. If store is nil, all operations will return a ServiceUnavailable error.
func NewAPIKeyServiceWithSync ¶
func NewAPIKeyServiceWithSync(store apikey.KeyStore, syncSvc SyncService) APIKeyService
NewAPIKeyServiceWithSync creates a new APIKeyService that forwards Create/Delete operations to the master cluster via the provided SyncService WS channel. Local List/Get continue to use the local store.
type ClusterConfigSink ¶
type ClusterConfigSink interface {
ApplyClusterConfig(ctx context.Context, cfg cluster.ClusterConfig) error
}
ClusterConfigSink receives ClusterConfig snapshots from ws-proxy and persists them (e.g. to a Kubernetes ConfigMap) so that other Worker components (ExtProc, in-process DNS resolver, ...) can read the latest state. Implementations must treat a zero-valued snapshot (no clusters and no host aliases) as a no-op.
type ClusterService ¶
type ClusterService interface {
// List returns the cluster catalog sorted by ID. When store or localID are
// empty the result is a single-entry list containing the local cluster, or an
// empty slice when neither is configured. The list is a defensive copy; the
// caller may mutate it freely.
List(ctx context.Context) ([]gen.ClusterSummary, *domain.AppError)
}
ClusterService exposes the routing-visible cluster list to API consumers. It wraps a cluster.Store and tags the local cluster so SDK/CLI callers can distinguish the native home of a request from remote worker clusters.
func NewClusterService ¶
func NewClusterService(store *cluster.Store, localClusterID string) ClusterService
NewClusterService returns a ClusterService backed by the given store and local cluster ID. store may be nil (common in single-cluster deployments); in that case List reports only the local cluster if localID is set.
type CreateAPIKeyInput ¶ added in v0.0.5
type CreateAPIKeyInput struct {
Namespace string
User string
Team string
Description string
ExpiresAt time.Time // zero means no expiry
// Import mode fields (admin-only).
// When TokenHash is non-empty the key is imported using the given hash
// (via CreateFromHash) instead of generating a new random token.
TokenHash string
HashPrefix string
IssuedAt time.Time // preserve original issue time (import mode)
}
CreateAPIKeyInput carries parameters for issuing a new API key.
type CreateKeyRequest ¶
type CreateKeyRequest struct {
Namespace string
User string
Team string
Role string
Description string
QuotaURL string
ExpiresAt string // RFC3339; empty = never expires
// Import/promote mode: when TokenHash + HashPrefix are set the Hub calls
// CreateFromHash instead of generating a new token.
TokenHash string
HashPrefix string
IssuedAt string // RFC3339
RawToken string // plaintext token for promote
}
CreateKeyRequest carries the parameters for forwarding an API key CreateKey RPC to the Hub.
type CreateKeyResponse ¶
type CreateKeyResponse struct {
RawToken string
KeyID string
TokenHash string
HashPrefix string
IssuedAt string // RFC3339
}
CreateKeyResponse is the parsed result of a successful Hub-side CreateKey.
type CreateSandboxEnvInput ¶ added in v0.0.5
type CreateSandboxEnvInput struct {
Name string
Namespace string
Team string // copied from auth, injected as label
User string // copied from auth, injected as label
TemplateRef agentsv1alpha1.SandboxEnvTemplateRef
Mode agentsv1alpha1.SandboxEnvMode
Overrides *agentsv1alpha1.EnvOverridesSpec
// ImagePullSecret, when non-nil, instructs the service to materialise a
// dockerconfigjson Secret named ips-{envName} with an OwnerRef pointing
// at the Env (cascade-delete free). The Env Reconciler stamps a
// LocalObjectReference to that Secret into every member Pool.
ImagePullSecret *gen.ImagePullSecretInput
Labels map[string]string
Annotations map[string]string
}
CreateSandboxEnvInput is the parsed CreateSandboxEnvRequest with auth context resolved. Members and Autoscaling are intentionally absent — the caller adds them via the embedded sub-services after the env shell is created.
type CreateSandboxInput ¶ added in v0.0.5
type CreateSandboxInput struct {
ClusterID string // target cluster ID parsed from pool name prefix; empty means local
PoolName string
Namespace string
Image string
ContainerImages map[string]string
Labels map[string]string
Annotations map[string]string
Metadata map[string]string
StartupTimeout time.Duration // 0 means no timeout
IdleTimeout time.Duration // 0 means no expiry
// RequestedScalingGroup, when non-empty, hard-scopes pool selection to the
// env's member pools whose autoscaling group
// (EnvClusterMemberConfig.ScalingGroup) equals this value. If no member of
// the env belongs to that group the create fails (503) rather than falling
// back to another group. Empty = no constraint. Set from the reserved
// metadata key MetaKeyScalingGroup by the create handlers.
RequestedScalingGroup string
// PostStartHooks are actions to run after the sandbox transitions Starting → Running.
// Serialized to a pod annotation at claim time; consumed by the controller.
PostStartHooks []poststarthooks.Action
// NetworkPolicy, when non-nil, overrides the Pool's Env-default egress policy
// for this sandbox only (E2B create body: network / allow_internet_access).
// Rejected when the target Pool has no networkPolicy (no filter sidecar).
NetworkPolicy *agentsv1alpha1.SandboxNetworkPolicy
}
CreateSandboxInput carries all parameters needed to create a new sandbox. The shape is service-internal: it holds parsed timeouts (durations), the cluster prefix already split out of the pool name, and post-start hooks (which are not part of the native wire spec — they are injected by the E2B compatibility handler).
type CrossClusterForwarder ¶
type CrossClusterForwarder struct {
// contains filtered or unexported fields
}
CrossClusterForwarder transparently forwards HTTP requests to a remote cluster's API endpoint. It is protocol-agnostic: the original gin.Context request (method, path, query string, headers, body) is forwarded verbatim; only the base URL is swapped according to urlKind and the target cluster's gateway configuration.
Callers (handlers) should:
- Detect the cross-cluster case early (right after extracting clusterID).
- Call Forward — it writes the remote response directly to gc.Writer.
- Return from the handler immediately after Forward returns.
func NewCrossClusterForwarder ¶
func NewCrossClusterForwarder(store *cluster.Store, localClusterID string) *CrossClusterForwarder
NewCrossClusterForwarder creates a forwarder. Returns nil if store or localClusterID is empty, which disables cross-cluster support.
The forwarder's HTTP client uses a custom Dialer that consults the Manager- pushed host-alias resolver before falling back to the system DNS, so that gateway hostnames unreachable via kube-dns (e.g. internal zones on the worker network) can be resolved purely via the sync channel without touching Pod spec.
func (*CrossClusterForwarder) Forward ¶
func (f *CrossClusterForwarder) Forward(gc *gin.Context, targetClusterID string, urlKind URLKind, body io.Reader)
Forward transparently proxies the incoming gin request to targetCluster. urlKind selects whether to target the Native or E2B endpoint.
body overrides the request body sent to the remote cluster. Pass nil to use gc.Request.Body as-is (suitable for GET/DELETE or when the body has not yet been consumed). Pass a non-nil reader when the handler has already read the body (e.g. strict-server mode where oapi-codegen parses the body before the handler runs) — in that case the caller should re-marshal the parsed struct and pass it here.
The full remote response (status, headers, body) is written directly to gc.Writer. On network/configuration errors, Forward writes a 502 JSON error response itself so the caller can always return immediately after this call.
func (*CrossClusterForwarder) IsCrossCluster ¶
func (f *CrossClusterForwarder) IsCrossCluster(clusterID string) bool
IsCrossCluster reports whether clusterID refers to a remote cluster that requires forwarding. Returns false when the forwarder is nil (cross-cluster disabled), clusterID is empty, or clusterID equals the local cluster.
func (*CrossClusterForwarder) LocalClusterID ¶
func (f *CrossClusterForwarder) LocalClusterID() string
LocalClusterID returns the configured local cluster ID. Empty when the forwarder is nil (cross-cluster disabled) or no local ID was configured.
type EnvRouter ¶ added in v0.0.5
type EnvRouter interface {
Resolve(ns, clusterID, poolOrEnvName string) envscheduler.ResolveResult
// SelectPool picks a member pool of envKey. scalingGroup, when non-empty,
// hard-scopes the choice to that autoscaling group (returns "" when the
// group has no member). Empty = no constraint.
SelectPool(envKey types.NamespacedName, scalingGroup string) string
// SelectForeignTarget returns the cluster ID and member pool a create for
// envKey should be forwarded to (local has no idle capacity for the group,
// a foreign cluster's member does); ok is false when it should be served
// locally.
SelectForeignTarget(envKey types.NamespacedName, scalingGroup string) (clusterID, memberPool string, ok bool)
}
EnvRouter is the subset of envscheduler.Manager that sandbox_service uses at request-entry time to translate bare template names into a target Pool. It is an interface (rather than a concrete *envscheduler.Manager) so unit tests can substitute a fake without standing up a real Manager.
May be nil — when nil, sandbox_service skips Env routing entirely and treats every template as a direct Pool reference (legacy behaviour, used by tests that don't wire the Env layer).
type EnvShellService ¶ added in v0.0.5
type EnvShellService interface {
// List returns a lightweight summary of the SandboxEnvs in namespace
// visible to the caller. When team/user are non-empty the result is
// filtered by the standard scheduling.navix.sh/{team,user} labels
// (matching the Pool model). Callers needing the full spec/status fetch
// each Env via Get.
List(ctx context.Context, namespace, team, user string) ([]gen.SandboxEnvSummary, *domain.AppError)
// Get returns a single Env or NotFound.
Get(ctx context.Context, namespace, name string) (*gen.SandboxEnv, *domain.AppError)
// Create posts a new SandboxEnv shell. The body carries TemplateRef +
// Overrides + optional ImagePullSecret only — Members are added via
// AddMember (from the embedded MemberPoolService), which also
// materialises the matching autoscaling group automatically.
Create(ctx context.Context, input CreateSandboxEnvInput) (*gen.SandboxEnv, *domain.AppError)
// Update patches Overrides / ImagePullSecret on an existing Env.
// Members and autoscaling groups are intentionally not part of this
// surface — use the dedicated CRUD methods from the embedded
// sub-services to avoid accidental wholesale replacement.
Update(ctx context.Context, input UpdateSandboxEnvInput) (*gen.SandboxEnv, *domain.AppError)
// Delete issues a foreground delete on the Env. Member Pools are
// cascade-deleted via OwnerReferences (controller=true,
// blockOwnerDeletion=true) stamped by the Env Reconciler.
Delete(ctx context.Context, namespace, name string) (*gen.DeleteSandboxEnvResult, *domain.AppError)
// ListEvents returns recent K8s Events emitted against the Env and its
// member SandboxPools, merged and sorted descending by lastTimestamp.
// Drives the activity timeline on the Env detail page in the dashboard.
ListEvents(ctx context.Context, namespace, name string, limit int) ([]gen.EnvEvent, *domain.AppError)
}
EnvShellService is the env-only CRUD slice of SandboxEnvService. Lives as its own interface so the composed SandboxEnvService can be assembled from three orthogonal contracts (env shell + member CRUD + autoscaler CRUD) without method-name collisions.
type ExecTokenInfo ¶ added in v0.0.5
ExecTokenInfo carries the information stored in an exec token. It is returned by ValidateExecToken after successful token validation.
type ExecTokenRecord ¶
type ExecTokenRecord struct {
SandboxID string
Namespace string
PodName string
Containers []string
ExpiresAt time.Time
}
ExecTokenRecord holds the information associated with a one-time exec token.
type ExtProcClient ¶
type ExtProcClient interface {
PushRoute(ctx context.Context, r RouteInfo) error
EvictRoute(ctx context.Context, sandboxID string) error
GetLastActive(ctx context.Context) (map[string]time.Time, error)
Close() error
}
ExtProcClient is the Controller-side view of the ExtProc control-plane RPC. Implementations are safe for concurrent use; close via Close when the process is shutting down.
func NewExtProcClient ¶
func NewExtProcClient(target, adminKey string) (ExtProcClient, error)
NewExtProcClient dials the ExtProc control-plane gRPC server at target and configures per-RPC admin-key credentials. target is a gRPC dial string (e.g. "agentbox-extproc.agentbox-system.svc:9003"). For backwards compatibility with the old HTTP flag value, any leading "http://" or "https://" scheme is stripped silently so stale deployment manifests keep working. adminKey may be empty in dev mode; the server side is expected to match.
type IAMResolveResult ¶
type IAMResolveResult struct {
// Username is the normalised username.
Username string
// Team is the team derived from ScitixQuota labels. Empty when no quota found.
Team string
// Namespace is the effective Kubernetes namespace to use for this user.
// When the computed namespace (t-{team}-{username}) exists in the cluster it
// equals that value; otherwise it falls back to "default".
Namespace string
// QuotaURL is the quota URL label value, if found.
QuotaURL string
}
IAMResolveResult holds the resolved identity information for an IAM user.
type IAMService ¶
type IAMService interface {
// ResolveNamespace resolves the effective namespace for a given team+user pair.
// Results are cached permanently (until process restart) for performance.
ResolveNamespace(ctx context.Context, team, user string) (string, *domain.AppError)
}
IAMService defines operations related to IAM identity resolution.
func NewIAMService ¶
func NewIAMService(c client.Client) IAMService
NewIAMService creates an IAMService backed by Kubernetes ScitixQuota CRs.
type KeyMetadata ¶ added in v0.0.5
type KeyMetadata struct {
// KeyID is the fully qualified secret identifier: "<namespace>/<name>".
KeyID string
Namespace string
Role string
User string
Team string
Description string
IssuedAt time.Time
ExpiresAt time.Time // zero value means no expiry
// SyncSource is "global" when the key was created/synced via ws-proxy.
// Empty means locally-created or a legacy resource — both are treated as non-global.
SyncSource string
// RawToken is the full raw API key recovered from storage. Empty for legacy keys
// that pre-date plaintext storage. Exposed via API to authorised callers for recovery.
RawToken string
}
KeyMetadata is the service-layer view of an API key's stored metadata. It is kept distinct from `apikey.KeyMetadata` (the K8s-Secret storage shape) so the service can evolve its presentation independently of the storage utility.
type LastCreateBumper ¶ added in v0.0.5
type LastCreateBumper interface {
// Bump records the current time as the most-recent Sandbox.Create
// for the named Pool. Must be safe to call from the request hot
// path; the production implementation takes a brief mutex on an
// in-memory map.
Bump(namespace, name string)
}
LastCreateBumper is the minimal interface k8sSandboxService needs from pkg/lifecycle/lastcreate.Tracker. Defined here (rather than imported) so the service package stays free of the concrete dependency and the tracker can be swapped/disabled in tests.
type ListSandboxesResult ¶
ListSandboxesResult wraps the paginated result and total count for List operations.
type OrganizationService ¶
type OrganizationService interface {
// ListTeams returns all unique team names found across API Key secrets.
ListTeams(ctx context.Context) ([]string, *domain.AppError)
// ListUsersByTeam returns all unique user names belonging to the given team,
// derived from API Key secrets filtered by team label.
ListUsersByTeam(ctx context.Context, team string) ([]string, *domain.AppError)
// ListNamespaces returns all Kubernetes namespace names visible to the operator.
ListNamespaces(ctx context.Context) ([]string, *domain.AppError)
}
OrganizationService defines operations for querying organizational structure (teams, users, namespaces) derived from API Key Secret labels.
func NewOrganizationService ¶
func NewOrganizationService(c client.Client, ks apikey.KeyStore) OrganizationService
NewOrganizationService creates an OrganizationService backed by Kubernetes resources. keyStore is used to enumerate teams and users via API Key Secret labels.
type QuotaService ¶
type QuotaService interface {
// ListForUser returns all quotas matching the given user and team. When
// the underlying provider is disabled the result is an empty list, not
// an error — callers should treat that as "feature unavailable".
ListForUser(ctx context.Context, user, team string) ([]gen.Quota, *domain.AppError)
}
QuotaService defines operations for querying user-visible quotas.
The concrete behaviour (ScitixQuota CRD, external API, disabled stub, ...) is selected by the quota.Provider injected at construction time. The service layer itself stays vendor-neutral — see pkg/plugins/quota for the provider contract and pkg/scitix/quota for the Scitix implementation.
func NewQuotaServiceFromProvider ¶
func NewQuotaServiceFromProvider(p quotaplugin.Provider) QuotaService
NewQuotaServiceFromProvider wraps a quota.Provider in the service-level interface consumed by HTTP handlers. The provider may be a Noop, which yields a service whose ListForUser always returns (nil, nil).
type RegistryStore ¶ added in v0.0.2
type RegistryStore interface {
LookupRegistry(host string) (clusterID, typ string, ok bool)
RegistryForType(clusterID, typ string) (host string, ok bool)
}
RegistryStore is the subset of cluster.Store used by RewriteImageForCluster. Extracted as an interface so tests can inject a lightweight fake without depending on the full Store implementation.
type RouteInfo ¶
RouteInfo is the set of fields the Controller pushes to ExtProc after a successful sandbox claim. SandboxID is the raw UUID (no cluster prefix). Phase and PodIP are intentionally absent: ExtProc reads both live from the Pod informer at request time, so this payload never carries stale state.
type SandboxEnvService ¶ added in v0.0.5
type SandboxEnvService interface {
EnvShellService
envmember.MemberPoolService
envautoscaler.AutoscalerService
}
SandboxEnvService is the business-layer surface for SandboxEnv resources. It composes the env shell CRUD with the two sub-resource interfaces (MemberPool CRUD + Autoscaler CRUD) so the router only needs to inject one service instance and handlers call e.g. s.env.AddMember(...) or s.env.UpdateAutoscalingGroup(...).
Method names on the sub-interfaces carry a noun suffix (AddMember, UpdateAutoscalingGroup, …) so embedding doesn't produce conflicts and the call site reads naturally.
func NewSandboxEnvService ¶ added in v0.0.5
func NewSandboxEnvService(c client.Client, pm *plugins.PluginManager, instProv instancetypeplugin.Provider, quotaProv quotaplugin.Provider) SandboxEnvService
NewSandboxEnvService constructs the default service implementation. The PluginManager / provider arguments flow through to the embedded MemberPoolService; the autoscaler sub-service currently needs only the k8s client. A nil *plugins.PluginManager is treated as "no plugins"; nil providers are normalised to their Noop forms inside envmember.New.
type SandboxListFilter ¶ added in v0.0.5
type SandboxListFilter struct {
Namespace string
PoolName string
Status string // comma-separated multi-value supported (e.g. "Running,Failed")
Team string // when non-empty, only return sandboxes with this team label
User string // when non-empty, only return sandboxes with this user label
Limit int // default 20, max 100; 0 means no limit
Offset int
}
SandboxListFilter is the service-side projection of gen.ListSandboxesParams: the (often pointer-typed) query params are dereferenced and combined with the auth-derived namespace/team/user.
type SandboxService ¶
type SandboxService interface {
Create(ctx context.Context, input CreateSandboxInput) (*gen.Sandbox, *domain.AppError)
List(ctx context.Context, filter SandboxListFilter) (*ListSandboxesResult, *domain.AppError)
Get(ctx context.Context, namespace, sandboxID string) (*gen.Sandbox, *domain.AppError)
Delete(ctx context.Context, namespace, sandboxID string) (*gen.DeleteSandboxResult, *domain.AppError)
// SetTimeout updates the idle timeout annotation on the sandbox pod.
// A timeout of 0 removes the annotation (no expiry).
SetTimeout(ctx context.Context, namespace, sandboxID string, timeout time.Duration) *domain.AppError
// GetLogs retrieves logs for a sandbox. For active sandboxes it fetches live
// logs from the K8s API; for runtime sources it reads the log file via exec.
GetLogs(ctx context.Context, namespace, sandboxID string, params gen.GetSandboxLogsParams) (*gen.SandboxLogsResult, *domain.AppError)
// CreateExecToken generates a single-use exec token (TTL 30 s) for the given sandbox.
// The sandbox must be in the Running phase.
CreateExecToken(ctx context.Context, namespace, sandboxID string) (string, *domain.AppError)
// ValidateExecToken validates and consumes the token.
// Returns ExecTokenInfo on success, or a 401 AppError if the token is invalid / expired.
ValidateExecToken(tokenStr string) (*ExecTokenInfo, *domain.AppError)
// ExecCommand runs a one-shot command inside the sandbox pod (non-interactive, no TTY).
// The sandbox must be in Running phase. clientset must be non-nil.
ExecCommand(ctx context.Context, namespace, sandboxID string, req gen.ExecCommandRequest) (*gen.ExecCommandResult, *domain.AppError)
// IsReady checks if all runtime readiness probes for a sandbox pass.
// If a runtime has no ReadinessProbe configured, it is considered ready.
IsReady(ctx context.Context, namespace, sandboxID string) (*gen.SandboxReadinessResult, *domain.AppError)
}
SandboxService defines business operations for sandboxes.
func NewSandboxService ¶
func NewSandboxService(c client.Client, cs kubernetes.Interface, restCfg *rest.Config, s store.SandboxStore, gatewayBaseURL string, localClusterID string, extprocClient ExtProcClient, registryStore RegistryStore) SandboxService
NewSandboxService creates a new SandboxService backed by the given K8s client and optional stores. clientset is used for live log retrieval and exec; it may be nil (live logs and exec will be unavailable). restConfig is the Kubernetes REST config for exec via SPDY; it may be nil (exec will be unavailable). gatewayBaseURL is the base URL of the Envoy gateway (e.g. http://gateway.example.com); it may be empty. localClusterID identifies the local cluster for cross-cluster sandbox ID prefixing; it may be empty. extprocClient pushes new sandbox routes to ExtProc so Create can return without polling; may be nil in tests. registryStore supplies per-cluster registry metadata for automatic image host rewriting; may be nil (no rewriting).
type SandboxTemplateService ¶
type SandboxTemplateService interface {
// List returns templates visible to the caller (auth). isAdmin=true bypasses
// visibility filtering and returns all templates.
List(ctx context.Context, auth domain.AuthInfo, isAdmin bool) ([]gen.SandboxTemplate, *domain.AppError)
// Get returns a single template if it is visible to the caller. isAdmin=true
// bypasses visibility filtering. Returns ErrCodeNotFound when the template
// does not exist or the caller cannot see it (to avoid leaking names).
Get(ctx context.Context, name string, auth domain.AuthInfo, isAdmin bool) (*gen.SandboxTemplate, *domain.AppError)
// Admin only:
Create(ctx context.Context, tmpl *agentsv1alpha1.SandboxTemplate) (*gen.SandboxTemplate, *domain.AppError)
Update(ctx context.Context, tmpl *agentsv1alpha1.SandboxTemplate) (*gen.SandboxTemplate, *domain.AppError)
Delete(ctx context.Context, name string) *domain.AppError
// CreateOrUpdate upserts a SandboxTemplate. It is used by SyncService to apply
// sync events from ws-proxy. The operation is idempotent: if the template already
// exists its spec is replaced; otherwise it is created.
CreateOrUpdate(ctx context.Context, tmpl *agentsv1alpha1.SandboxTemplate) *domain.AppError
// StripStaleGlobalLabels removes the sync-source=global label from any local
// template whose name is NOT present in knownNames. This corrects templates
// that were mistakenly (or historically) labeled as global but no longer exist
// on the master cluster, preventing delete requests from being forwarded to
// ws-proxy and receiving a 404.
StripStaleGlobalLabels(ctx context.Context, knownNames map[string]struct{}) *domain.AppError
}
SandboxTemplateService defines business operations for SandboxTemplates.
func NewSandboxTemplateService ¶
func NewSandboxTemplateService(c client.Client) SandboxTemplateService
NewSandboxTemplateService creates a new SandboxTemplateService backed by the given K8s client.
type SyncHTTPError ¶
SyncHTTPError carries an HTTP-style status code translated from a gRPC status code. It is the cross-package error type that pkg/apiserver/handlers/server.go uses to map sync forwarding failures into the appropriate native API responses.
func (*SyncHTTPError) Error ¶ added in v0.0.3
func (e *SyncHTTPError) Error() string
type SyncService ¶
type SyncService interface {
// OnConnect registers a new ClientConn (produced by wsmux.DialGRPC after
// a fresh /v1/ws/sync upgrade). Returns a connection generation ID that
// must be passed back to OnDisconnect so that a stale teardown does not
// race against a newer connect.
OnConnect(conn *grpc.ClientConn) uint64
// OnDisconnect tears down all background Watch goroutines associated
// with connID and clears the ClientConn — but only if connID still
// matches the currently-registered conn.
OnDisconnect(connID uint64)
RequestCreate(ctx context.Context, req CreateKeyRequest) (*CreateKeyResponse, error)
RequestDelete(ctx context.Context, name string) error
RequestTemplateCreate(ctx context.Context, raw json.RawMessage) error
RequestTemplateUpdate(ctx context.Context, raw json.RawMessage) error
RequestTemplateDelete(ctx context.Context, name string) error
}
SyncService manages the gRPC client connection to ws-proxy. It exposes synchronous request methods for the apiserver business layer and runs background goroutines that consume the three Watch* streams to keep the local KeyStore / SandboxTemplate / ClusterConfig state up to date.
func NewSyncService ¶
func NewSyncService(store apikey.KeyStore) SyncService
NewSyncService creates a new SyncService.
func NewSyncServiceFull ¶
func NewSyncServiceFull(store apikey.KeyStore, templateSvc SandboxTemplateService, clusterSink ClusterConfigSink) SyncService
NewSyncServiceFull creates a SyncService with all optional components wired in.
func NewSyncServiceWithTemplate ¶
func NewSyncServiceWithTemplate(store apikey.KeyStore, templateSvc SandboxTemplateService) SyncService
NewSyncServiceWithTemplate creates a SyncService that also handles SandboxTemplate sync events.
type URLKind ¶
URLKind selects which base URL from GatewayConfig to use when forwarding. It is an alias for cluster.URLKind so existing callers keep their import surface while the header-merge logic shares the canonical enum.
type UpdateSandboxEnvInput ¶ added in v0.0.5
type UpdateSandboxEnvInput struct {
Name string
Namespace string
Overrides *agentsv1alpha1.EnvOverridesSpec
// ImagePullSecret, when non-nil, upserts the dockerconfigjson Secret
// backing this Env's image-pull credentials. Nil means leave existing
// Secret untouched.
ImagePullSecret *gen.ImagePullSecretInput
}
UpdateSandboxEnvInput carries the editable patch for an Env shell. Members and Autoscaling are intentionally not exposed here so callers can't accidentally wholesale-replace either set; use the dedicated sub-service methods instead.
Source Files
¶
- apikey_inputs.go
- apikey_service.go
- cluster_service.go
- cross_cluster_forwarder.go
- egress_policy.go
- env_imagepull.go
- exec_token_store.go
- extproc_client.go
- iam_service.go
- image_rewrite.go
- image_validation.go
- inputs.go
- organization_service.go
- quota_service.go
- sandbox_service.go
- sandboxenv_events.go
- sandboxenv_service.go
- sandboxtemplate_service.go
- sync_service.go
- sync_service_federation.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package envautoscaler serves the Env-scoped autoscaler-config CRUD surface.
|
Package envautoscaler serves the Env-scoped autoscaler-config CRUD surface. |
|
Package envcommon hosts the helpers shared between the env shell service (pkg/apiserver/service) and the per-resource sub-services (envmember, envautoscaler).
|
Package envcommon hosts the helpers shared between the env shell service (pkg/apiserver/service) and the per-resource sub-services (envmember, envautoscaler). |
|
Package envmember serves the Env-scoped Pool CRUD surface: `/v1/sandboxenvs/{name}/sandboxpools/*`.
|
Package envmember serves the Env-scoped Pool CRUD surface: `/v1/sandboxenvs/{name}/sandboxpools/*`. |
|
Package envscheduler implements the in-process Env-level request router.
|
Package envscheduler implements the in-process Env-level request router. |
|
Package federation holds the Worker-side soft-state view of cross-cluster SandboxEnv capacity.
|
Package federation holds the Worker-side soft-state view of cross-cluster SandboxEnv capacity. |