Documentation
¶
Overview ¶
Package v1alpha1 contains API Schema definitions for the muster v1alpha1 API group.
This package defines the Kubernetes Custom Resource Definitions (CRDs) for muster's core components. The v1alpha1 API version represents the initial alpha release of the muster Kubernetes API and is subject to change.
API Group: muster.giantswarm.io/v1alpha1 ¶
## MCPServer
MCPServer represents a Model Context Protocol server definition and runtime state. It consolidates configuration and runtime information for MCP servers that provide tools and capabilities to the muster system.
MCPServers can be configured as local command processes with specific command arguments, environment variables, and lifecycle behavior.
Example:
apiVersion: muster.giantswarm.io/v1alpha1
kind: MCPServer
metadata:
name: git-tools
namespace: default
spec:
name: git-tools
type: localCommand
autoStart: true
toolPrefix: git
command: ["npx", "@modelcontextprotocol/server-git"]
env:
GIT_ROOT: "/workspace"
description: "Git tools MCP server for repository operations"
+kubebuilder:object:generate=true +groupName=muster.giantswarm.io
Package v1alpha1 contains API Schema definitions for the muster v1alpha1 API group +kubebuilder:object:generate=true +groupName=muster.giantswarm.io
Index ¶
- Variables
- type ArgDefinition
- type ClientCredentialsSecretRef
- type IssuerURL
- type LocalMintConfig
- type MCPServer
- type MCPServerAuth
- type MCPServerAuthAuthorizationServer
- type MCPServerFamily
- type MCPServerList
- type MCPServerSpec
- type MCPServerStateValue
- type MCPServerStatus
- type TokenExchangeConfig
- type Workflow
- type WorkflowCondition
- type WorkflowConditionExpectation
- type WorkflowForEach
- type WorkflowList
- type WorkflowSpec
- type WorkflowStatus
- type WorkflowStep
- type WorkflowSubStep
Constants ¶
This section is empty.
Variables ¶
var ( // GroupVersion is group version used to register these objects GroupVersion = schema.GroupVersion{Group: "muster.giantswarm.io", Version: "v1alpha1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} //nolint:staticcheck // controller-runtime/pkg/scheme.Builder is the established kubebuilder pattern // AddToScheme adds the types in this group-version to the given scheme. AddToScheme = SchemeBuilder.AddToScheme )
Functions ¶
This section is empty.
Types ¶
type ArgDefinition ¶
type ArgDefinition struct {
// +kubebuilder:validation:Required
// +kubebuilder:validation:Enum=string;integer;boolean;number;object;array
Type string `json:"type" yaml:"type"`
// Required indicates whether this argument must be provided.
// +kubebuilder:default=false
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
// Default provides a default value when the argument is omitted.
// +kubebuilder:validation:XPreserveUnknownFields
Default *apiextensionsv1.JSON `json:"default,omitempty" yaml:"default,omitempty"`
// Description provides human-readable documentation.
// +kubebuilder:validation:MaxLength=500
Description string `json:"description,omitempty" yaml:"description,omitempty"`
}
ArgDefinition defines validation rules and metadata for a single workflow argument. It specifies the expected type, whether the argument is required, an optional default, and a human-readable description.
func (*ArgDefinition) DeepCopy ¶
func (in *ArgDefinition) DeepCopy() *ArgDefinition
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgDefinition.
func (*ArgDefinition) DeepCopyInto ¶
func (in *ArgDefinition) DeepCopyInto(out *ArgDefinition)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type ClientCredentialsSecretRef ¶
type ClientCredentialsSecretRef struct {
// Name is the name of the Kubernetes Secret.
// Required.
Name string `json:"name" yaml:"name"`
// Namespace is the Kubernetes namespace where the secret is located.
// If not specified, defaults to the MCPServer's namespace.
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
// ClientIDKey is the key in the secret data that contains the client ID.
// Defaults to "client-id" if not specified.
// +kubebuilder:default="client-id"
ClientIDKey string `json:"clientIdKey,omitempty" yaml:"clientIdKey,omitempty"`
// ClientSecretKey is the key in the secret data that contains the client secret.
// Defaults to "client-secret" if not specified.
// +kubebuilder:default="client-secret"
ClientSecretKey string `json:"clientSecretKey,omitempty" yaml:"clientSecretKey,omitempty"`
}
ClientCredentialsSecretRef references a Kubernetes Secret containing OAuth client credentials for token exchange authentication.
func (*ClientCredentialsSecretRef) DeepCopy ¶
func (in *ClientCredentialsSecretRef) DeepCopy() *ClientCredentialsSecretRef
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientCredentialsSecretRef.
func (*ClientCredentialsSecretRef) DeepCopyInto ¶
func (in *ClientCredentialsSecretRef) DeepCopyInto(out *ClientCredentialsSecretRef)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type IssuerURL ¶ added in v0.1.142
type IssuerURL string
IssuerURL is a normalized OAuth/OIDC issuer URL. Per RFC 8414 §2: HTTPS, no trailing slash, no fragment, no query string.
Accepted: https://issuer.example.com
https://issuer.example.com:8443 https://issuer.example.com/tenant https://login.microsoftonline.com/<tenant-uuid>/v2.0
Rejected: https://issuer.example.com/ (trailing slash)
https://issuer.example.com#frag (fragment) https://issuer.example.com?x=1 (query) http://issuer.example.com (non-HTTPS)
+kubebuilder:validation:Pattern=`^https://[^/?#]+(/[^?#]*[^/?#])?$`
type LocalMintConfig ¶ added in v0.13.0
type LocalMintConfig struct {
// Enabled turns on local minting for this server.
// +kubebuilder:default=false
Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"`
// Audience is the minted token's aud claim: the backend's resource identifier.
// It must equal a configured broker local-mint target; the mint fails closed
// when no matching target exists.
// +kubebuilder:validation:MinLength=1
Audience string `json:"audience,omitempty" yaml:"audience,omitempty"`
}
LocalMintConfig configures the per-backend token mint (see MCPServerAuth.LocalMint).
func (*LocalMintConfig) DeepCopy ¶ added in v0.13.0
func (in *LocalMintConfig) DeepCopy() *LocalMintConfig
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalMintConfig.
func (*LocalMintConfig) DeepCopyInto ¶ added in v0.13.0
func (in *LocalMintConfig) DeepCopyInto(out *LocalMintConfig)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type MCPServer ¶
type MCPServer struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec MCPServerSpec `json:"spec,omitempty"`
Status MCPServerStatus `json:"status,omitempty"`
}
MCPServer is the Schema for the mcpservers API
func (*MCPServer) DeepCopy ¶
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MCPServer.
func (*MCPServer) DeepCopyInto ¶
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (*MCPServer) DeepCopyObject ¶
DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
type MCPServerAuth ¶
type MCPServerAuth struct {
// Type specifies the authentication type.
// Supported values:
// - "oauth": OAuth 2.0/OIDC authentication
// - "none": No authentication
// +kubebuilder:validation:Enum=oauth;none
// +kubebuilder:default=none
Type string `json:"type,omitempty" yaml:"type,omitempty"`
// ForwardToken enables ID token forwarding for SSO.
// When true, muster forwards the user's ID token to this server instead of
// triggering a separate OAuth flow. The downstream server must be configured
// to trust muster's client ID in its TrustedAudiences.
// +kubebuilder:default=false
ForwardToken bool `json:"forwardToken,omitempty" yaml:"forwardToken,omitempty"`
// RequiredAudiences specifies additional audience(s) that the forwarded ID token
// should contain. When ForwardToken is true, muster will request these audiences
// from the upstream IdP (e.g., Dex) using cross-client scopes.
//
// This is used when the downstream server requires tokens with specific audiences,
// for example when forwarding tokens to Kubernetes for OIDC authentication:
// requiredAudiences:
// - "dex-k8s-authenticator"
//
// At user authentication, muster collects all requiredAudiences from MCPServers
// with forwardToken: true and requests them all from the IdP.
RequiredAudiences []string `json:"requiredAudiences,omitempty" yaml:"requiredAudiences,omitempty"`
// TokenExchange enables SSO via RFC 8693 Token Exchange for cross-cluster SSO.
// When configured, muster exchanges its local token for a token valid on the
// remote cluster's Identity Provider (e.g., Dex).
//
// Use TokenExchange when:
// - The remote cluster has its own Dex instance
// - The remote Dex is configured with an OIDC connector for muster's Dex
// - You need a token issued by the remote cluster's IdP (not just forwarded)
//
// Token exchange takes precedence over ForwardToken if both are configured.
TokenExchange *TokenExchangeConfig `json:"tokenExchange,omitempty" yaml:"tokenExchange,omitempty"`
// AuthorizationServer is an opt-out for backends that don't publish RFC 9728
// Protected Resource Metadata. When set, muster's per-server OAuth login flow
// (core_auth_login) skips PRM probing and uses these values directly. muster
// logs each override use at INFO so non-compliance is observable.
//
// This override does NOT bypass mcp-go's connect-time PRM probe; backends
// without RFC 9728 metadata still reconcile to "Auth Required" on first
// connect, then transition to "Connected" after `muster auth login`.
//
// Setting AuthorizationServer does NOT change the RFC 8707 `resource`
// parameter — that remains driven by the MCP server URL.
//
// AuthorizationServer is mutually exclusive with ForwardToken: true and
// TokenExchange.Enabled: true. The CRD admission rules above reject any
// CR that combines them. Only valid when Type is "oauth".
//
// Use case: Atlassian Remote MCP and similar backends that publish RFC 8414
// metadata at their resource origin instead of via RFC 9728.
AuthorizationServer *MCPServerAuthAuthorizationServer `json:"authorizationServer,omitempty" yaml:"authorizationServer,omitempty"`
// LocalMint enables downstream auth via a per-backend token minted by muster
// from its own signing key. On each call muster reads the caller's bearer as
// the subject and an optional X-Actor-Token header as the actor, then mints a
// token (sub=subject, act=actor, aud=Audience, iss=muster) through muster's
// RFC 8693 broker, which enforces ActorDelegationPolicy and WorkloadAudiences.
//
// Use LocalMint when the backend must authorize an agent acting for itself
// (M2M) or on behalf of a human (OBO) and no shared remote IdP can issue a
// token with the backend's audience. Requires muster's OAuth server to run in
// JWT mode with a broker local-mint target whose audience equals Audience.
//
// LocalMint is mutually exclusive with ForwardToken, TokenExchange, and
// AuthorizationServer (the CRD admission rules above reject combinations).
LocalMint *LocalMintConfig `json:"localMint,omitempty" yaml:"localMint,omitempty"`
}
MCPServerAuth configures authentication behavior for an MCP server. This enables Single Sign-On (SSO) via token forwarding between muster and downstream MCP servers that share the same Identity Provider. +kubebuilder:validation:XValidation:rule="!has(self.authorizationServer) || self.type == 'oauth'",message="authorizationServer is only valid when type is oauth" +kubebuilder:validation:XValidation:rule="!(has(self.forwardToken) && self.forwardToken == true && has(self.authorizationServer))",message="forwardToken bypasses per-backend OAuth; set one or the other, not both" +kubebuilder:validation:XValidation:rule="!(has(self.tokenExchange) && has(self.tokenExchange.enabled) && self.tokenExchange.enabled == true && has(self.authorizationServer))",message="tokenExchange has its own issuer/endpoint config; set one or the other, not both" +kubebuilder:validation:XValidation:rule="!(has(self.localMint) && self.localMint.enabled == true && has(self.forwardToken) && self.forwardToken == true)",message="localMint and forwardToken are mutually exclusive downstream auth modes; set one" +kubebuilder:validation:XValidation:rule="!(has(self.localMint) && self.localMint.enabled == true && has(self.tokenExchange) && has(self.tokenExchange.enabled) && self.tokenExchange.enabled == true)",message="localMint and tokenExchange are mutually exclusive downstream auth modes; set one" +kubebuilder:validation:XValidation:rule="!(has(self.localMint) && self.localMint.enabled == true && has(self.authorizationServer))",message="localMint mints muster's own token; it cannot be combined with authorizationServer"
func (*MCPServerAuth) DeepCopy ¶
func (in *MCPServerAuth) DeepCopy() *MCPServerAuth
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MCPServerAuth.
func (*MCPServerAuth) DeepCopyInto ¶
func (in *MCPServerAuth) DeepCopyInto(out *MCPServerAuth)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type MCPServerAuthAuthorizationServer ¶ added in v0.1.142
type MCPServerAuthAuthorizationServer struct {
// Issuer is the OAuth 2.0 / OIDC issuer URL.
// muster fetches AS metadata via the existing OAuth client, which performs
// RFC 8414 / OIDC discovery against this issuer.
// +kubebuilder:validation:Required
Issuer IssuerURL `json:"issuer" yaml:"issuer"`
// Scopes is the OAuth scope parameter value (RFC 6749 §3.3 wire format:
// space-separated scope tokens). Matches existing TokenExchangeConfig.Scopes.
// +optional
Scopes string `json:"scopes,omitempty" yaml:"scopes,omitempty"`
}
MCPServerAuthAuthorizationServer pins the OAuth authorization server for an MCP server when RFC 9728 PRM discovery is unavailable.
func (*MCPServerAuthAuthorizationServer) DeepCopy ¶ added in v0.1.142
func (in *MCPServerAuthAuthorizationServer) DeepCopy() *MCPServerAuthAuthorizationServer
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MCPServerAuthAuthorizationServer.
func (*MCPServerAuthAuthorizationServer) DeepCopyInto ¶ added in v0.1.142
func (in *MCPServerAuthAuthorizationServer) DeepCopyInto(out *MCPServerAuthAuthorizationServer)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type MCPServerFamily ¶ added in v0.1.180
type MCPServerFamily struct {
// Name is the family identifier. Servers sharing the same Name expose
// their tools as {musterPrefix}_{Name}_{toolName}.
// +kubebuilder:validation:Required
// +kubebuilder:validation:Pattern="^[a-zA-Z][a-zA-Z0-9_-]*$"
Name string `json:"name" yaml:"name"`
// InstanceArg names the required parameter callers use to select which
// family member handles the tool call (for example "management_cluster",
// "country", "model"). All servers declaring the same family.name must
// agree on InstanceArg; if they diverge, the aggregator falls back to
// per-server prefixing for the entire family and logs a warning.
// +kubebuilder:validation:Required
// +kubebuilder:validation:Pattern="^[a-zA-Z][a-zA-Z0-9_]*$"
InstanceArg string `json:"instanceArg" yaml:"instanceArg"`
}
MCPServerFamily groups equivalent MCP server instances under a shared exposed surface. When MCPServerSpec.Family is set, the aggregator emits a single family-scoped tool per backend tool name with a required parameter (named by InstanceArg) that selects which instance handles the call.
func (*MCPServerFamily) DeepCopy ¶ added in v0.1.180
func (in *MCPServerFamily) DeepCopy() *MCPServerFamily
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MCPServerFamily.
func (*MCPServerFamily) DeepCopyInto ¶ added in v0.1.180
func (in *MCPServerFamily) DeepCopyInto(out *MCPServerFamily)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type MCPServerList ¶
type MCPServerList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []MCPServer `json:"items"`
}
MCPServerList contains a list of MCPServer
func (*MCPServerList) DeepCopy ¶
func (in *MCPServerList) DeepCopy() *MCPServerList
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MCPServerList.
func (*MCPServerList) DeepCopyInto ¶
func (in *MCPServerList) DeepCopyInto(out *MCPServerList)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (*MCPServerList) DeepCopyObject ¶
func (in *MCPServerList) DeepCopyObject() runtime.Object
DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
type MCPServerSpec ¶
type MCPServerSpec struct {
// Type specifies how this MCP server should be executed.
// Supported values: "stdio" for local processes, "streamable-http" for HTTP-based servers, "sse" for Server-Sent Events
// +kubebuilder:validation:Required
// +kubebuilder:validation:Enum=stdio;streamable-http;sse
Type string `json:"type" yaml:"type"`
// ToolPrefix is an optional prefix that will be prepended to all tool names
// provided by this MCP server. This helps avoid naming conflicts when multiple
// servers provide tools with similar names.
// +kubebuilder:validation:Pattern="^[a-zA-Z][a-zA-Z0-9_-]*$"
ToolPrefix string `json:"toolPrefix,omitempty" yaml:"toolPrefix,omitempty"`
// Family declares that this MCP server is an instance of a family of
// equivalent servers (for example, multiple kubernetes MCP servers pointed
// at different clusters). When set, the aggregator exposes tools from all
// servers in the same family under a single name
// ({musterPrefix}_{family.name}_{toolName}) with a required parameter
// (named by family.instanceArg) that selects which instance handles the
// call. The parameter is always required even for single-instance families
// so skills written against the family name remain stable as instances are
// added or removed. When unset, the legacy per-server prefixing applies
// ({musterPrefix}_{toolPrefix-or-name}_{toolName}).
Family *MCPServerFamily `json:"family,omitempty" yaml:"family,omitempty"`
// Description provides a human-readable description of this MCP server's purpose.
// +kubebuilder:validation:MaxLength=500
Description string `json:"description,omitempty" yaml:"description,omitempty"`
// AutoStart determines whether this MCP server should be automatically started
// when the muster system initializes or when dependencies become available.
// +kubebuilder:default=false
AutoStart bool `json:"autoStart,omitempty" yaml:"autoStart,omitempty"`
// Command specifies the executable path for stdio type servers.
// This field is required when Type is "stdio".
Command string `json:"command,omitempty" yaml:"command,omitempty"`
// Args specifies the command line arguments for stdio type servers.
// This field is only available when Type is "stdio".
Args []string `json:"args,omitempty" yaml:"args,omitempty"`
// URL is the endpoint where the remote MCP server can be reached
// This field is required when Type is "streamable-http" or "sse".
// Examples: http://mcp-server:8080/mcp, https://api.example.com/mcp
// +kubebuilder:validation:Pattern=`^https?://[^\s/$.?#].[^\s]*$`
URL string `json:"url,omitempty" yaml:"url,omitempty"`
// Env contains environment variables to set for the MCP server.
// For stdio servers, these are passed to the process when it is started.
// For remote servers, these can be used for authentication or configuration.
Env map[string]string `json:"env,omitempty" yaml:"env,omitempty"`
// Headers contains HTTP headers to send with requests to remote MCP servers.
// This field is only relevant when Type is "streamable-http" or "sse".
Headers map[string]string `json:"headers,omitempty" yaml:"headers,omitempty"`
// Auth configures authentication behavior for this MCP server.
// This is only relevant for remote servers (streamable-http or sse).
Auth *MCPServerAuth `json:"auth,omitempty" yaml:"auth,omitempty"`
// Timeout specifies the connection timeout for remote operations (in seconds)
// +kubebuilder:default=30
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=300
Timeout int `json:"timeout,omitempty" yaml:"timeout,omitempty"`
}
MCPServerSpec defines the desired state of MCPServer
func (*MCPServerSpec) DeepCopy ¶
func (in *MCPServerSpec) DeepCopy() *MCPServerSpec
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MCPServerSpec.
func (*MCPServerSpec) DeepCopyInto ¶
func (in *MCPServerSpec) DeepCopyInto(out *MCPServerSpec)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type MCPServerStateValue ¶
type MCPServerStateValue string
MCPServerStateValue represents the high-level infrastructure state of an MCPServer. This is independent of user session state (authentication, per-user connection status).
Status values reflect infrastructure availability with context-appropriate terminology:
For stdio (local process) servers:
- Running: Process is running and responding
- Starting: Process is being started
- Stopped: Process is not running (initial state or explicitly stopped)
- Failed: Process crashed or cannot be started
For remote (streamable-http, sse) servers:
- Connected: TCP connection established and authenticated
- AuthRequired: Server is reachable but requires authentication (returned 401)
- Connecting: Attempting to establish connection
- Disconnected: Not connected (initial state or connection closed)
- Failed: Endpoint unreachable (network error, DNS failure, etc.)
const ( // MCPServerStateRunning indicates a stdio server process is running. MCPServerStateRunning MCPServerStateValue = "Running" // MCPServerStateStarting indicates a stdio server process is being started. MCPServerStateStarting MCPServerStateValue = "Starting" // MCPServerStateStopped indicates a stdio server process is not running. MCPServerStateStopped MCPServerStateValue = "Stopped" // MCPServerStateConnected indicates a remote server is reachable and authenticated. // The server responded successfully (not 401/403). MCPServerStateConnected MCPServerStateValue = "Connected" // MCPServerStateAuthRequired indicates a remote server is reachable but requires authentication. // The server returned a 401 Unauthorized response, indicating it IS reachable at the // network level but needs OAuth authentication before it can be used. // Users should run `muster auth login --server <name>` to authenticate. MCPServerStateAuthRequired MCPServerStateValue = "Auth Required" // MCPServerStateConnecting indicates a connection attempt is in progress. MCPServerStateConnecting MCPServerStateValue = "Connecting" // MCPServerStateDisconnected indicates a remote server is not connected. MCPServerStateDisconnected MCPServerStateValue = "Disconnected" // MCPServerStateFailed indicates infrastructure is not available. // For stdio: process crashed or cannot be started. // For http/sse: endpoint unreachable (network error, DNS failure, etc.). MCPServerStateFailed MCPServerStateValue = "Failed" )
type MCPServerStatus ¶
type MCPServerStatus struct {
// State represents the high-level infrastructure state of the MCP server.
// This is independent of user session state (authentication, connection status).
//
// For stdio servers: Running, Starting, Stopped, Failed
// For remote servers: Connected, Auth Required, Connecting, Disconnected, Failed
// +kubebuilder:validation:Enum=Running;Starting;Stopped;Connected;Auth Required;Connecting;Disconnected;Failed
State MCPServerStateValue `json:"state,omitempty" yaml:"state,omitempty"`
// LastError contains any error message from the most recent server operation.
// Note: Per-user authentication errors are tracked in the Session Registry,
// not here. This field only contains infrastructure-level errors.
LastError string `json:"lastError,omitempty" yaml:"lastError,omitempty"`
// LastConnected indicates when the server was last successfully connected
LastConnected *metav1.Time `json:"lastConnected,omitempty" yaml:"lastConnected,omitempty"`
// RestartCount tracks how many times this server has been restarted (stdio only)
RestartCount int `json:"restartCount,omitempty" yaml:"restartCount,omitempty"`
// ConsecutiveFailures tracks the number of consecutive connection failures.
// This is used for exponential backoff and to identify unreachable servers.
// Reset to 0 when a connection succeeds.
ConsecutiveFailures int `json:"consecutiveFailures,omitempty" yaml:"consecutiveFailures,omitempty"`
// LastAttempt indicates when the last connection attempt was made.
// Used with ConsecutiveFailures to implement exponential backoff.
LastAttempt *metav1.Time `json:"lastAttempt,omitempty" yaml:"lastAttempt,omitempty"`
// NextRetryAfter indicates the earliest time when the next retry should be attempted.
// This is calculated based on exponential backoff from ConsecutiveFailures.
NextRetryAfter *metav1.Time `json:"nextRetryAfter,omitempty" yaml:"nextRetryAfter,omitempty"`
// Conditions represent the latest available observations of the MCPServer's current state.
// Standard condition types:
// - Ready: True if infrastructure is reachable (process running or TCP connectable)
Conditions []metav1.Condition `json:"conditions,omitempty" yaml:"conditions,omitempty"`
}
MCPServerStatus defines the observed state of MCPServer.
This status reflects server-side observable state including auth requirements. It captures infrastructure connectivity as well as whether the server demands authentication (e.g. "Auth Required"). Per-user session state (which specific user is authenticated, token expiry, etc.) is tracked separately in the Session Registry (internal/aggregator/session_registry.go).
Server-Side State (CRD):
- State: Running/Connected/Starting/Connecting/Stopped/Disconnected/Auth Required/Failed
- Conditions: Standard K8s conditions for detailed status
Per-User Session State (Session Registry):
- ConnectionStatus: Connected, PendingAuth, Failed (per-user)
- AuthStatus: Authenticated, AuthRequired, TokenExpired (per-user)
- AvailableTools: Tools visible to this specific user
func (*MCPServerStatus) DeepCopy ¶
func (in *MCPServerStatus) DeepCopy() *MCPServerStatus
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MCPServerStatus.
func (*MCPServerStatus) DeepCopyInto ¶
func (in *MCPServerStatus) DeepCopyInto(out *MCPServerStatus)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type TokenExchangeConfig ¶
type TokenExchangeConfig struct {
// Enabled determines whether token exchange should be attempted.
// +kubebuilder:default=false
Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"`
// DexTokenEndpoint is the URL used to connect to the remote cluster's Dex token endpoint.
// This may differ from the issuer URL when access goes through a proxy.
// Required when Enabled is true.
// Example: https://dex.cluster-b.example.com/token (direct)
// Example: https://dex-cluster.proxy.example.com/token (via proxy)
// +kubebuilder:validation:Pattern=`^https://[^\s/$.?#].[^\s]*$`
DexTokenEndpoint string `json:"dexTokenEndpoint,omitempty" yaml:"dexTokenEndpoint,omitempty"`
// ExpectedIssuer is the expected issuer URL in the exchanged token's "iss" claim.
// This should match the remote Dex's configured issuer URL.
// When access goes through a proxy, this differs from DexTokenEndpoint.
// If not specified, the issuer is derived from DexTokenEndpoint (backward compatible).
// Example: https://dex.cluster-b.example.com
// +kubebuilder:validation:Pattern=`^https://[^\s/$.?#].[^\s]*$`
ExpectedIssuer string `json:"expectedIssuer,omitempty" yaml:"expectedIssuer,omitempty"`
// ConnectorID is the ID of the OIDC connector on the remote Dex that
// trusts the local cluster's Dex.
// Required when Enabled is true.
// Example: "cluster-a-dex"
// +kubebuilder:validation:Pattern="^[a-zA-Z][a-zA-Z0-9_-]*$"
ConnectorID string `json:"connectorId,omitempty" yaml:"connectorId,omitempty"`
// Scopes are the scopes to request for the exchanged token.
// +kubebuilder:default="openid profile email groups"
Scopes string `json:"scopes,omitempty" yaml:"scopes,omitempty"`
// ClientCredentialsSecretRef references a Kubernetes Secret containing
// client credentials for authenticating with the remote Dex's token endpoint.
// This is required when the remote Dex requires client authentication for
// token exchange (RFC 8693).
//
// The secret should contain:
// - client-id: The OAuth client ID registered on the remote Dex
// - client-secret: The OAuth client secret for authentication
//
// Example secret:
//
// apiVersion: v1
// kind: Secret
// metadata:
// name: grizzly-token-exchange-credentials
// namespace: muster
// type: Opaque
// stringData:
// client-id: muster-token-exchange
// client-secret: <secret-value>
ClientCredentialsSecretRef *ClientCredentialsSecretRef `json:"clientCredentialsSecretRef,omitempty" yaml:"clientCredentialsSecretRef,omitempty"`
}
TokenExchangeConfig configures RFC 8693 Token Exchange for cross-cluster SSO. This enables muster to exchange its local token for a token valid on a remote cluster's Identity Provider (typically Dex).
The remote Dex must be configured with an OIDC connector that trusts the local cluster's Dex. For example:
# On remote cluster's Dex (cluster-b)
connectors:
- type: oidc
id: cluster-a-dex
name: "Cluster A"
config:
issuer: https://dex.cluster-a.example.com
getUserInfo: true
insecureEnableGroups: true
func (*TokenExchangeConfig) DeepCopy ¶
func (in *TokenExchangeConfig) DeepCopy() *TokenExchangeConfig
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TokenExchangeConfig.
func (*TokenExchangeConfig) DeepCopyInto ¶
func (in *TokenExchangeConfig) DeepCopyInto(out *TokenExchangeConfig)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type Workflow ¶
type Workflow struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec WorkflowSpec `json:"spec,omitempty"`
Status WorkflowStatus `json:"status,omitempty"`
}
Workflow is the Schema for the workflows API
func (*Workflow) DeepCopy ¶
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Workflow.
func (*Workflow) DeepCopyInto ¶
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (*Workflow) DeepCopyObject ¶
DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
type WorkflowCondition ¶
type WorkflowCondition struct {
// Template is a boolean Go-template gate. When set, the step executes only
// if the template renders to "true" (e.g. "{{ eq .input.env \"production\" }}").
// Mutually exclusive with Tool/FromStep; when present, Expect/ExpectNot are ignored.
Template string `json:"template,omitempty" yaml:"template,omitempty"`
// Tool specifies the name of the tool to execute for condition evaluation.
// Optional when FromStep or Template is used.
Tool string `json:"tool,omitempty" yaml:"tool,omitempty"`
// Args provides the arguments to pass to the condition tool.
// Values may be any JSON type.
Args map[string]apiextensionsv1.JSON `json:"args,omitempty" yaml:"args,omitempty"`
// FromStep specifies the step ID to reference for condition evaluation.
FromStep string `json:"fromStep,omitempty" yaml:"fromStep,omitempty"`
// Expect defines positive health check expectations.
Expect *WorkflowConditionExpectation `json:"expect,omitempty" yaml:"expect,omitempty"`
// ExpectNot defines negative health check expectations.
ExpectNot *WorkflowConditionExpectation `json:"expectNot,omitempty" yaml:"expectNot,omitempty"`
}
WorkflowCondition defines execution conditions for workflow steps. A condition selects its evaluation source with exactly one of Template, Tool, or FromStep. A tool/fromStep condition must declare an Expect or ExpectNot: without one the executor falls back to expecting the call to fail, which is rarely intended. +kubebuilder:validation:XValidation:rule="(has(self.template) ? 1 : 0) + (has(self.tool) ? 1 : 0) + (has(self.fromStep) ? 1 : 0) == 1",message="exactly one of template, tool, or fromStep must be set" +kubebuilder:validation:XValidation:rule="has(self.template) || has(self.expect) || has(self.expectNot)",message="a tool or fromStep condition requires expect or expectNot"
func (*WorkflowCondition) DeepCopy ¶
func (in *WorkflowCondition) DeepCopy() *WorkflowCondition
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowCondition.
func (*WorkflowCondition) DeepCopyInto ¶
func (in *WorkflowCondition) DeepCopyInto(out *WorkflowCondition)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type WorkflowConditionExpectation ¶
type WorkflowConditionExpectation struct {
// Success indicates whether the tool call should succeed.
Success *bool `json:"success,omitempty" yaml:"success,omitempty"`
// JsonPath defines JSON path conditions to check in the result.
// Values may be any JSON type (typically scalars compared to a result field).
JsonPath map[string]apiextensionsv1.JSON `json:"jsonPath,omitempty" yaml:"jsonPath,omitempty"`
}
WorkflowConditionExpectation defines expected outcomes for workflow conditions
func (*WorkflowConditionExpectation) DeepCopy ¶
func (in *WorkflowConditionExpectation) DeepCopy() *WorkflowConditionExpectation
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowConditionExpectation.
func (*WorkflowConditionExpectation) DeepCopyInto ¶
func (in *WorkflowConditionExpectation) DeepCopyInto(out *WorkflowConditionExpectation)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type WorkflowForEach ¶ added in v0.8.0
type WorkflowForEach struct {
// Items is a template expression that must resolve to an array, e.g.
// "{{ .input.clusters }}". Each element is bound to the loop variable for
// the duration of one iteration.
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinLength=1
Items string `json:"items" yaml:"items"`
// As is the loop variable name made available to the body as
// "{{ .vars.<as> }}". Defaults to "item".
// +kubebuilder:default=item
As string `json:"as,omitempty" yaml:"as,omitempty"`
// Steps is the body executed for each item.
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinItems=1
Steps []WorkflowSubStep `json:"steps" yaml:"steps"`
}
WorkflowForEach describes a sequential loop over a list of items. The body is a flat list of sub-steps (no nested forEach/parallel), executed once per item.
func (*WorkflowForEach) DeepCopy ¶ added in v0.8.0
func (in *WorkflowForEach) DeepCopy() *WorkflowForEach
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowForEach.
func (*WorkflowForEach) DeepCopyInto ¶ added in v0.8.0
func (in *WorkflowForEach) DeepCopyInto(out *WorkflowForEach)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type WorkflowList ¶
type WorkflowList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Workflow `json:"items"`
}
WorkflowList contains a list of Workflow
func (*WorkflowList) DeepCopy ¶
func (in *WorkflowList) DeepCopy() *WorkflowList
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowList.
func (*WorkflowList) DeepCopyInto ¶
func (in *WorkflowList) DeepCopyInto(out *WorkflowList)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (*WorkflowList) DeepCopyObject ¶
func (in *WorkflowList) DeepCopyObject() runtime.Object
DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
type WorkflowSpec ¶
type WorkflowSpec struct {
// Description provides a human-readable description of the workflow's purpose.
// +kubebuilder:validation:MaxLength=1000
Description string `json:"description,omitempty" yaml:"description,omitempty"`
// Args defines the argument schema for workflow execution validation.
Args map[string]ArgDefinition `json:"args,omitempty" yaml:"args,omitempty"`
// Steps defines the sequence of workflow steps defining the execution flow.
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinItems=1
Steps []WorkflowStep `json:"steps" yaml:"steps"`
// OnFailure defines best-effort cleanup/rollback steps that run when the
// workflow fails on a step that does not allow failure. The steps execute
// sequentially and their own failures are tolerated.
OnFailure []WorkflowSubStep `json:"onFailure,omitempty" yaml:"onFailure,omitempty"`
// Output is an optional templated projection that shapes the workflow's
// returned document. It is rendered once after all steps complete, against
// .input / .results / .vars, and replaces the default
// {execution_id, workflow, status, input, steps[], ...} envelope. Each leaf
// is a Go-template/sprig expression; JSON structure is preserved so numbers
// stay numbers and arrays stay arrays (e.g. "{{ .results.pods.items }}" or
// "{{ len .results.events.items }}"). A leaf's type comes from the value it
// evaluates to, not from how its rendered text looks: a single-action leaf
// keeps its real type (a number stays a number, "{{ len .x }}" is a number),
// and a computed string keeps its exact string form, so values whose form
// matters (leading zeros, versions, IDs like "08" or "1.20") are preserved
// without any coercion or workaround. Every step result is referenceable
// here regardless of its output flag. When omitted, the default envelope is
// returned unchanged.
// +kubebuilder:validation:XPreserveUnknownFields
Output map[string]apiextensionsv1.JSON `json:"output,omitempty" yaml:"output,omitempty"`
}
WorkflowSpec defines the desired state of Workflow
func (*WorkflowSpec) DeepCopy ¶
func (in *WorkflowSpec) DeepCopy() *WorkflowSpec
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowSpec.
func (*WorkflowSpec) DeepCopyInto ¶
func (in *WorkflowSpec) DeepCopyInto(out *WorkflowSpec)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type WorkflowStatus ¶
type WorkflowStatus struct {
// Valid indicates whether the Workflow spec passes structural validation.
Valid bool `json:"valid,omitempty" yaml:"valid,omitempty"`
// ValidationErrors contains any spec validation error messages.
ValidationErrors []string `json:"validationErrors,omitempty" yaml:"validationErrors,omitempty"`
// ReferencedTools lists all tools mentioned in the Workflow steps.
// This is informational only; actual availability depends on the user's session.
// See ADR 007 for details on session-scoped tool visibility.
ReferencedTools []string `json:"referencedTools,omitempty" yaml:"referencedTools,omitempty"`
// StepCount is the number of steps in the workflow.
StepCount int `json:"stepCount,omitempty" yaml:"stepCount,omitempty"`
// Conditions represent the latest available observations of the workflow's state.
Conditions []metav1.Condition `json:"conditions,omitempty" yaml:"conditions,omitempty"`
}
WorkflowStatus defines the observed state of Workflow
func (*WorkflowStatus) DeepCopy ¶
func (in *WorkflowStatus) DeepCopy() *WorkflowStatus
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowStatus.
func (*WorkflowStatus) DeepCopyInto ¶
func (in *WorkflowStatus) DeepCopyInto(out *WorkflowStatus)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type WorkflowStep ¶
type WorkflowStep struct {
// ID is the unique identifier for this step within the workflow.
// +kubebuilder:validation:Required
// +kubebuilder:validation:Pattern="^[a-zA-Z0-9_-]+$"
// +kubebuilder:validation:MaxLength=63
ID string `json:"id" yaml:"id"`
// Tool specifies the name of the tool to execute for this step.
// Mutually exclusive with forEach and parallel.
Tool string `json:"tool,omitempty" yaml:"tool,omitempty"`
// Args provides arguments for the tool execution (supports templating).
// Values may be any JSON type (string, integer, boolean, number, object, array)
// because the schema uses x-kubernetes-preserve-unknown-fields. Templated
// strings such as "{{.input.namespace}}" are resolved server-side at
// execution time.
Args map[string]apiextensionsv1.JSON `json:"args,omitempty" yaml:"args,omitempty"`
// Condition defines an optional condition that determines whether this step should execute.
Condition *WorkflowCondition `json:"condition,omitempty" yaml:"condition,omitempty"`
// ForEach executes a body of sub-steps once per item of a list. Mutually
// exclusive with tool and parallel.
ForEach *WorkflowForEach `json:"forEach,omitempty" yaml:"forEach,omitempty"`
// Parallel executes a group of sub-steps concurrently. Each sub-step
// resolves its arguments from the workflow state as it was before the
// group started; siblings cannot reference each other's results. Mutually
// exclusive with tool and forEach.
// +kubebuilder:validation:MinItems=1
Parallel []WorkflowSubStep `json:"parallel,omitempty" yaml:"parallel,omitempty"`
// Output indicates whether this step's result is included in the workflow's
// returned document (what the caller receives). Every step result is always
// referenceable by later steps via {{ .results.<id>.<field> }} regardless of
// this flag; Output only controls visibility in the returned result. When
// unset, the deprecated Store flag is used as a fallback.
Output *bool `json:"output,omitempty" yaml:"output,omitempty"`
// Store is a deprecated alias for Output. It originally also controlled
// whether a step result was referenceable by later steps, but referencing
// is now always available; Store now only affects result visibility and is
// kept for backwards compatibility. Prefer Output.
// +kubebuilder:default=false
Store bool `json:"store,omitempty" yaml:"store,omitempty"`
// AllowFailure defines if in case of an error the next step is executed or not.
// +kubebuilder:default=false
AllowFailure bool `json:"allowFailure,omitempty" yaml:"allowFailure,omitempty"`
// Description provides human-readable documentation for this step's purpose.
// +kubebuilder:validation:MaxLength=500
Description string `json:"description,omitempty" yaml:"description,omitempty"`
}
WorkflowStep defines a single step in the workflow execution. A step is exactly one of: a tool call (tool), a sequential loop (forEach), or a concurrent group (parallel). +kubebuilder:validation:XValidation:rule="(has(self.tool) ? 1 : 0) + (has(self.forEach) ? 1 : 0) + (has(self.parallel) ? 1 : 0) == 1",message="exactly one of tool, forEach, or parallel must be set"
func (*WorkflowStep) DeepCopy ¶
func (in *WorkflowStep) DeepCopy() *WorkflowStep
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowStep.
func (*WorkflowStep) DeepCopyInto ¶
func (in *WorkflowStep) DeepCopyInto(out *WorkflowStep)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type WorkflowSubStep ¶ added in v0.8.0
type WorkflowSubStep struct {
// ID is the unique identifier for this sub-step.
// +kubebuilder:validation:Required
// +kubebuilder:validation:Pattern="^[a-zA-Z0-9_-]+$"
// +kubebuilder:validation:MaxLength=63
ID string `json:"id" yaml:"id"`
// Tool specifies the name of the tool to execute.
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinLength=1
Tool string `json:"tool" yaml:"tool"`
// Args provides arguments for the tool execution (supports templating).
Args map[string]apiextensionsv1.JSON `json:"args,omitempty" yaml:"args,omitempty"`
// Condition defines an optional condition that determines whether this sub-step should execute.
Condition *WorkflowCondition `json:"condition,omitempty" yaml:"condition,omitempty"`
// Output indicates whether this sub-step's result is included in the
// workflow's returned document. The result is always referenceable by later
// steps regardless of this flag. When unset, the deprecated Store flag is
// used as a fallback.
Output *bool `json:"output,omitempty" yaml:"output,omitempty"`
// Store is a deprecated alias for Output, kept for backwards compatibility.
// Prefer Output.
// +kubebuilder:default=false
Store bool `json:"store,omitempty" yaml:"store,omitempty"`
// AllowFailure defines if in case of an error execution continues.
// +kubebuilder:default=false
AllowFailure bool `json:"allowFailure,omitempty" yaml:"allowFailure,omitempty"`
// Description provides human-readable documentation for this sub-step's purpose.
// +kubebuilder:validation:MaxLength=500
Description string `json:"description,omitempty" yaml:"description,omitempty"`
}
WorkflowSubStep is a tool-call step used inside forEach bodies, parallel groups, and onFailure handlers. Unlike WorkflowStep it cannot itself contain forEach or parallel, which keeps the CRD schema structural (non-recursive).
func (*WorkflowSubStep) DeepCopy ¶ added in v0.8.0
func (in *WorkflowSubStep) DeepCopy() *WorkflowSubStep
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowSubStep.
func (*WorkflowSubStep) DeepCopyInto ¶ added in v0.8.0
func (in *WorkflowSubStep) DeepCopyInto(out *WorkflowSubStep)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.