CRDs: Provider, Channel, ToolBinding, AgentConfig + resource refs
- Provider CRD: cluster-scoped, API key from Secrets, model lists with pricing - Channel CRD: Discord/Slack/Telegram bindings with bot token refs - ToolBinding CRD: per-tool risk tiers with pattern escalation for exec-like tools - AgentConfig CRD: reusable config templates mirroring agents.defaults.* - Agent: now references AgentConfig, ToolBinding, Channel, Provider by name - AgentGroup: same resource refs + shared config inheritance
This commit is contained in:
parent
1a831bdfe5
commit
4bc4e0e442
6 changed files with 497 additions and 10 deletions
|
|
@ -12,27 +12,48 @@ import (
|
|||
|
||||
// AgentSpec defines the desired state of an Agent.
|
||||
type AgentSpec struct {
|
||||
// AgentID is the OpenClaw agent identifier (e.g., "main", "engineering").
|
||||
AgentID string `json:"agentId"`
|
||||
|
||||
// Model is the LLM model identifier (e.g., "deepseek-v4-pro:cloud").
|
||||
Model string `json:"model"`
|
||||
// +optional
|
||||
Model string `json:"model,omitempty"`
|
||||
|
||||
// Thinking is the thinking level override (e.g., "off", "low", "high").
|
||||
// +optional
|
||||
Thinking string `json:"thinking,omitempty"`
|
||||
|
||||
// Workspace configures the agent workspace volume and config.
|
||||
Workspace AgentWorkspace `json:"workspace"`
|
||||
// AgentConfigRef references an AgentConfig template.
|
||||
// +optional
|
||||
AgentConfigRef string `json:"agentConfigRef,omitempty"`
|
||||
|
||||
// Channels configures the communication channels for this agent.
|
||||
// Workspace configures the agent workspace volume and config.
|
||||
// +optional
|
||||
Workspace *AgentWorkspace `json:"workspace,omitempty"`
|
||||
|
||||
// Providers lists the provider references for this agent.
|
||||
// +optional
|
||||
Providers []string `json:"providers,omitempty"`
|
||||
|
||||
// ChannelRefs lists the Channel resources this agent should bind to.
|
||||
// +optional
|
||||
ChannelRefs []string `json:"channelRefs,omitempty"`
|
||||
|
||||
// Channels configures inline channel bindings (alternative to ChannelRefs).
|
||||
// +optional
|
||||
Channels []AgentChannel `json:"channels,omitempty"`
|
||||
|
||||
// ToolBindingRefs lists ToolBinding resources for this agent.
|
||||
// +optional
|
||||
ToolBindingRefs []string `json:"toolBindingRefs,omitempty"`
|
||||
|
||||
// Judge configures the Agent Judge authorization layer.
|
||||
// +optional
|
||||
Judge AgentJudgeConfig `json:"judge,omitempty"`
|
||||
Judge *AgentJudgeConfig `json:"judge,omitempty"`
|
||||
|
||||
// Resources defines compute resource requirements.
|
||||
// +optional
|
||||
Resources ResourceRequirements `json:"resources,omitempty"`
|
||||
Resources *ResourceRequirements `json:"resources,omitempty"`
|
||||
|
||||
// Image is the container image to run. Defaults to the Kubeclaw agent runner.
|
||||
// +optional
|
||||
|
|
@ -41,9 +62,6 @@ type AgentSpec struct {
|
|||
// Replicas is the number of agent instances. Defaults to 1.
|
||||
// +optional
|
||||
Replicas *int32 `json:"replicas,omitempty"`
|
||||
|
||||
// AgentID is the OpenClaw agent identifier (e.g., "main", "engineering").
|
||||
AgentID string `json:"agentId"`
|
||||
}
|
||||
|
||||
// AgentWorkspace configures the workspace for the agent.
|
||||
|
|
|
|||
154
api/v1alpha1/agentconfig_types.go
Normal file
154
api/v1alpha1/agentconfig_types.go
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
Copyright 2025 Scott Scoble.
|
||||
|
||||
Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// AgentConfigSpec mirrors OpenClaw's agents.defaults.* configuration block.
|
||||
// It's a reusable template that Agent resources can reference.
|
||||
type AgentConfigSpec struct {
|
||||
// Model is the default LLM model.
|
||||
// +optional
|
||||
Model string `json:"model,omitempty"`
|
||||
|
||||
// Thinking is the thinking level (off/low/high).
|
||||
// +optional
|
||||
Thinking string `json:"thinking,omitempty"`
|
||||
|
||||
// Workspace configures the agent workspace.
|
||||
// +optional
|
||||
Workspace *WorkspaceConfig `json:"workspace,omitempty"`
|
||||
|
||||
// MemorySearch configures memory search behavior.
|
||||
// +optional
|
||||
MemorySearch *MemorySearchConfig `json:"memorySearch,omitempty"`
|
||||
|
||||
// Heartbeat configures the agent heartbeat.
|
||||
// +optional
|
||||
Heartbeat *HeartbeatConfig `json:"heartbeat,omitempty"`
|
||||
|
||||
// Skills configures skill loading.
|
||||
// +optional
|
||||
Skills *SkillsConfig `json:"skills,omitempty"`
|
||||
|
||||
// Sandbox configures the execution sandbox.
|
||||
// +optional
|
||||
Sandbox *SandboxConfig `json:"sandbox,omitempty"`
|
||||
|
||||
// Tools controls tool availability.
|
||||
// +optional
|
||||
Tools *ToolsConfig `json:"tools,omitempty"`
|
||||
}
|
||||
|
||||
// WorkspaceConfig mirrors the workspace directory config.
|
||||
type WorkspaceConfig struct {
|
||||
// Dir is the workspace root directory.
|
||||
Dir string `json:"dir"`
|
||||
}
|
||||
|
||||
// MemorySearchConfig mirrors memory search defaults.
|
||||
type MemorySearchConfig struct {
|
||||
// Enabled controls memory search availability.
|
||||
// +optional
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
|
||||
// MaxResults limits search results.
|
||||
// +optional
|
||||
MaxResults int `json:"maxResults,omitempty"`
|
||||
|
||||
// MinScore is the minimum relevance score.
|
||||
// +optional
|
||||
MinScore float64 `json:"minScore,omitempty"`
|
||||
}
|
||||
|
||||
// HeartbeatConfig mirrors the heartbeat configuration.
|
||||
type HeartbeatConfig struct {
|
||||
// Enabled controls the heartbeat.
|
||||
// +optional
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
|
||||
// Interval is the heartbeat check interval.
|
||||
// +optional
|
||||
Interval string `json:"interval,omitempty"`
|
||||
|
||||
// Prompt is the heartbeat trigger prompt.
|
||||
// +optional
|
||||
Prompt string `json:"prompt,omitempty"`
|
||||
}
|
||||
|
||||
// SkillsConfig mirrors skill loading config.
|
||||
type SkillsConfig struct {
|
||||
// Allowed is a list of allowed skill IDs.
|
||||
// +optional
|
||||
Allowed []string `json:"allowed,omitempty"`
|
||||
|
||||
// Denied is a list of denied skill IDs.
|
||||
// +optional
|
||||
Denied []string `json:"denied,omitempty"`
|
||||
}
|
||||
|
||||
// SandboxConfig mirrors the sandbox configuration.
|
||||
type SandboxConfig struct {
|
||||
// Enabled controls sandbox containment.
|
||||
// +optional
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
|
||||
// AllowedExec is a list of allowed executable paths.
|
||||
// +optional
|
||||
AllowedExec []string `json:"allowedExec,omitempty"`
|
||||
}
|
||||
|
||||
// ToolsConfig mirrors tool configuration.
|
||||
type ToolsConfig struct {
|
||||
// Allow controls tool allowlist.
|
||||
// +optional
|
||||
Allow []string `json:"allow,omitempty"`
|
||||
|
||||
// Deny controls tool denylist.
|
||||
// +optional
|
||||
Deny []string `json:"deny,omitempty"`
|
||||
}
|
||||
|
||||
// AgentConfigStatus defines the observed state of an AgentConfig.
|
||||
type AgentConfigStatus struct {
|
||||
// Ready indicates the template is valid.
|
||||
Ready bool `json:"ready"`
|
||||
|
||||
// Validated indicates the config was validated.
|
||||
Validated bool `json:"validated"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:scope=Namespaced
|
||||
// +kubebuilder:printcolumn:name="DefaultModel",type=string,JSONPath=`.spec.model`
|
||||
// +kubebuilder:printcolumn:name="Ready",type=boolean,JSONPath=`.status.ready`
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
|
||||
// AgentConfig is a reusable configuration template for agents.
|
||||
type AgentConfig struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec AgentConfigSpec `json:"spec,omitempty"`
|
||||
Status AgentConfigStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// AgentConfigList contains a list of AgentConfig.
|
||||
type AgentConfigList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []AgentConfig `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&AgentConfig{}, &AgentConfigList{})
|
||||
}
|
||||
|
|
@ -15,6 +15,18 @@ type AgentGroupSpec struct {
|
|||
// Agents lists the agents in this group.
|
||||
Agents []AgentGroupMember `json:"agents"`
|
||||
|
||||
// AgentConfigRef references an AgentConfig template for all members.
|
||||
// +optional
|
||||
AgentConfigRef string `json:"agentConfigRef,omitempty"`
|
||||
|
||||
// ProviderRefs lists Provider resources for the group.
|
||||
// +optional
|
||||
ProviderRefs []string `json:"providerRefs,omitempty"`
|
||||
|
||||
// ChannelRefs lists Channel resources for the group.
|
||||
// +optional
|
||||
ChannelRefs []string `json:"channelRefs,omitempty"`
|
||||
|
||||
// SharedWorkspace references a ConfigMap with shared workspace config.
|
||||
// +optional
|
||||
SharedWorkspaceConfigMap string `json:"sharedWorkspaceConfigMap,omitempty"`
|
||||
|
|
@ -27,9 +39,13 @@ type AgentGroupSpec struct {
|
|||
// +optional
|
||||
JudgePolicyRef string `json:"judgePolicyRef,omitempty"`
|
||||
|
||||
// ToolBindingRefs lists ToolBinding resources for the group.
|
||||
// +optional
|
||||
ToolBindingRefs []string `json:"toolBindingRefs,omitempty"`
|
||||
|
||||
// NetworkPolicy controls inter-agent communication.
|
||||
// +optional
|
||||
NetworkPolicy NetworkPolicySpec `json:"networkPolicy,omitempty"`
|
||||
NetworkPolicy *NetworkPolicySpec `json:"networkPolicy,omitempty"`
|
||||
}
|
||||
|
||||
// AgentGroupMember defines a member of an AgentGroup.
|
||||
|
|
|
|||
84
api/v1alpha1/channel_types.go
Normal file
84
api/v1alpha1/channel_types.go
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
Copyright 2025 Scott Scoble.
|
||||
|
||||
Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// ChannelSpec defines a communication channel binding.
|
||||
type ChannelSpec struct {
|
||||
// Type is the channel platform (e.g., "discord", "slack", "telegram", "signal").
|
||||
Type string `json:"type"`
|
||||
|
||||
// Enabled controls whether this channel is active.
|
||||
// +optional
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
|
||||
// BotTokenSecretRef references a Secret containing the bot token.
|
||||
BotTokenSecretRef *corev1.SecretKeySelector `json:"botTokenSecretRef"`
|
||||
|
||||
// WebhookURL is the incoming webhook URL (for outbound-only channels).
|
||||
// +optional
|
||||
WebhookURL string `json:"webhookUrl,omitempty"`
|
||||
|
||||
// GuildID is the Discord/Telegram group identifier.
|
||||
// +optional
|
||||
GuildID string `json:"guildId,omitempty"`
|
||||
|
||||
// AdditionalConfig is platform-specific configuration passed as-is.
|
||||
// +optional
|
||||
AdditionalConfig map[string]string `json:"additionalConfig,omitempty"`
|
||||
}
|
||||
|
||||
// ChannelStatus defines the observed state of a Channel.
|
||||
type ChannelStatus struct {
|
||||
// Ready is true if the channel connection is established.
|
||||
Ready bool `json:"ready"`
|
||||
|
||||
// ConnectionState is the current connection state.
|
||||
// +optional
|
||||
ConnectionState string `json:"connectionState,omitempty"`
|
||||
|
||||
// LastConnected is when the channel was last successfully connected.
|
||||
// +optional
|
||||
LastConnected *metav1.Time `json:"lastConnected,omitempty"`
|
||||
|
||||
// ConnectedAgents lists agents currently bound to this channel.
|
||||
// +optional
|
||||
ConnectedAgents []string `json:"connectedAgents,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:scope=Namespaced
|
||||
// +kubebuilder:printcolumn:name="Type",type=string,JSONPath=`.spec.type`
|
||||
// +kubebuilder:printcolumn:name="Ready",type=boolean,JSONPath=`.status.ready`
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
|
||||
// Channel is the Schema for the channels API.
|
||||
type Channel struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ChannelSpec `json:"spec,omitempty"`
|
||||
Status ChannelStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// ChannelList contains a list of Channel.
|
||||
type ChannelList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Channel `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Channel{}, &ChannelList{})
|
||||
}
|
||||
100
api/v1alpha1/provider_types.go
Normal file
100
api/v1alpha1/provider_types.go
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
Copyright 2025 Scott Scoble.
|
||||
|
||||
Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// ProviderSpec defines an LLM provider configuration.
|
||||
type ProviderSpec struct {
|
||||
// Type is the provider type (e.g., "ollama", "openai", "anthropic", "deepseek").
|
||||
Type string `json:"type"`
|
||||
|
||||
// BaseURL is the provider API endpoint.
|
||||
// +optional
|
||||
BaseURL string `json:"baseUrl,omitempty"`
|
||||
|
||||
// APIKeySecretRef references a Secret key containing the API key.
|
||||
// +optional
|
||||
APIKeySecretRef *corev1.SecretKeySelector `json:"apiKeySecretRef,omitempty"`
|
||||
|
||||
// Models is the list of model identifiers available through this provider.
|
||||
// +optional
|
||||
Models []ProviderModel `json:"models,omitempty"`
|
||||
|
||||
// ExtraHeaders are additional HTTP headers for provider requests.
|
||||
// +optional
|
||||
ExtraHeaders map[string]string `json:"extraHeaders,omitempty"`
|
||||
}
|
||||
|
||||
// ProviderModel defines a single model within a provider.
|
||||
type ProviderModel struct {
|
||||
// ID is the model identifier (e.g., "deepseek-v4-pro:cloud").
|
||||
ID string `json:"id"`
|
||||
|
||||
// Default is true if this is the default model for the provider.
|
||||
// +optional
|
||||
Default bool `json:"default,omitempty"`
|
||||
|
||||
// Cost configures pricing for this model.
|
||||
// +optional
|
||||
Cost *ModelCost `json:"cost,omitempty"`
|
||||
}
|
||||
|
||||
// ModelCost defines pricing for a model.
|
||||
type ModelCost struct {
|
||||
// Input is the cost per million input tokens.
|
||||
Input float64 `json:"input"`
|
||||
|
||||
// Output is the cost per million output tokens.
|
||||
Output float64 `json:"output"`
|
||||
}
|
||||
|
||||
// ProviderStatus defines the observed state of a Provider.
|
||||
type ProviderStatus struct {
|
||||
// Ready is true if the provider is reachable and configured.
|
||||
Ready bool `json:"ready"`
|
||||
|
||||
// Condition is the current condition of the provider.
|
||||
// +optional
|
||||
Condition string `json:"condition,omitempty"`
|
||||
|
||||
// LastChecked is when the provider was last validated.
|
||||
// +optional
|
||||
LastChecked *metav1.Time `json:"lastChecked,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:scope=Cluster
|
||||
// +kubebuilder:printcolumn:name="Type",type=string,JSONPath=`.spec.type`
|
||||
// +kubebuilder:printcolumn:name="Ready",type=boolean,JSONPath=`.status.ready`
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
|
||||
// Provider is the Schema for the providers API.
|
||||
type Provider struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ProviderSpec `json:"spec,omitempty"`
|
||||
Status ProviderStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// ProviderList contains a list of Provider.
|
||||
type ProviderList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Provider `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Provider{}, &ProviderList{})
|
||||
}
|
||||
115
api/v1alpha1/toolbinding_types.go
Normal file
115
api/v1alpha1/toolbinding_types.go
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
Copyright 2025 Scott Scoble.
|
||||
|
||||
Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// ToolBindingSpec defines which tools an agent can use and their risk tiers.
|
||||
type ToolBindingSpec struct {
|
||||
// Tools is a list of tool access rules.
|
||||
Tools []ToolRule `json:"tools"`
|
||||
|
||||
// DefaultTier is the risk tier for tools not explicitly listed.
|
||||
// +optional
|
||||
// +kubebuilder:validation:Enum=no-judge;lightweight-approval;full-judge-review;human-only;denied
|
||||
DefaultTier string `json:"defaultTier,omitempty"`
|
||||
|
||||
// TargetAgentRefs lists agents or agent groups this binding applies to.
|
||||
// If empty, applies cluster-wide.
|
||||
// +optional
|
||||
TargetAgentRefs []TargetRef `json:"targetAgentRefs,omitempty"`
|
||||
}
|
||||
|
||||
// ToolRule defines access rules for a single tool or tool pattern.
|
||||
type ToolRule struct {
|
||||
// Name is the tool name or glob pattern (e.g., "exec", "read", "web_*").
|
||||
Name string `json:"name"`
|
||||
|
||||
// Tier is the risk tier for this tool.
|
||||
// +kubebuilder:validation:Enum=no-judge;lightweight-approval;full-judge-review;human-only;denied
|
||||
Tier string `json:"tier"`
|
||||
|
||||
// Patterns are inline script escalation patterns for exec-like tools.
|
||||
// +optional
|
||||
Patterns []RiskPattern `json:"patterns,omitempty"`
|
||||
|
||||
// Reason is a human-readable explanation for this rule.
|
||||
// +optional
|
||||
Reason string `json:"reason,omitempty"`
|
||||
}
|
||||
|
||||
// RiskPattern defines a pattern to watch for within a tool's parameters.
|
||||
type RiskPattern struct {
|
||||
// Name is a descriptive name (e.g., "inline-script-execution").
|
||||
Name string `json:"name"`
|
||||
|
||||
// Pattern is the match pattern (glob or regex).
|
||||
Pattern string `json:"pattern"`
|
||||
|
||||
// EscalateTier is the tier to escalate to when matched.
|
||||
// +kubebuilder:validation:Enum=lightweight-approval;full-judge-review;human-only
|
||||
EscalateTier string `json:"escalateTier"`
|
||||
}
|
||||
|
||||
// TargetRef identifies a target resource.
|
||||
type TargetRef struct {
|
||||
// Kind is the resource kind (Agent, AgentGroup, or empty for all).
|
||||
// +optional
|
||||
// +kubebuilder:validation:Enum=Agent;AgentGroup
|
||||
Kind string `json:"kind,omitempty"`
|
||||
|
||||
// Name is the resource name.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Namespace scopes the target (empty = all namespaces).
|
||||
// +optional
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
}
|
||||
|
||||
// ToolBindingStatus defines the observed state of a ToolBinding.
|
||||
type ToolBindingStatus struct {
|
||||
// Ready indicates the binding is active and enforced.
|
||||
Ready bool `json:"ready"`
|
||||
|
||||
// BoundAgents is the count of agents currently using this binding.
|
||||
BoundAgents int `json:"boundAgents,omitempty"`
|
||||
|
||||
// LastUpdated is when this binding was last reconciled.
|
||||
// +optional
|
||||
LastUpdated *metav1.Time `json:"lastUpdated,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:scope=Cluster
|
||||
// +kubebuilder:printcolumn:name="DefaultTier",type=string,JSONPath=`.spec.defaultTier`
|
||||
// +kubebuilder:printcolumn:name="Ready",type=boolean,JSONPath=`.status.ready`
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
|
||||
// ToolBinding is the Schema for the toolbindings API.
|
||||
type ToolBinding struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ToolBindingSpec `json:"spec,omitempty"`
|
||||
Status ToolBindingStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// ToolBindingList contains a list of ToolBinding.
|
||||
type ToolBindingList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []ToolBinding `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&ToolBinding{}, &ToolBindingList{})
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue