apis/v1alpha1/internalmembercluster_types.go (58 lines of code) (raw):
/*
Copyright 2025 The KubeFleet Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
import (
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +kubebuilder:object:root=true
// +kubebuilder:resource:scope=Namespaced,categories={fleet},shortName=imc
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:JSONPath=`.metadata.creationTimestamp`,name="Age",type=date
// InternalMemberCluster is used by hub agent to notify the member agents about the member cluster state changes, and is used by the member agents to report their status.
type InternalMemberCluster struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
// The desired state of InternalMemberCluster.
// +required
Spec InternalMemberClusterSpec `json:"spec"`
// The observed status of InternalMemberCluster.
// +optional
Status InternalMemberClusterStatus `json:"status,omitempty"`
}
// InternalMemberClusterSpec defines the desired state of InternalMemberCluster. Set by the hub agent.
type InternalMemberClusterSpec struct {
// +kubebuilder:validation:Required,Enum=Join;Leave
// The desired state of the member cluster. Possible values: Join, Leave.
// +required
State ClusterState `json:"state"`
// +kubebuilder:default=60
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=600
// How often (in seconds) for the member cluster to send a heartbeat to the hub cluster. Default: 60 seconds. Min: 1 second. Max: 10 minutes.
// +optional
HeartbeatPeriodSeconds int32 `json:"heartbeatPeriodSeconds,omitempty"`
}
// InternalMemberClusterStatus defines the observed state of InternalMemberCluster.
type InternalMemberClusterStatus struct {
// The current observed resource usage of the member cluster. It is populated by the member agent.
// +optional
ResourceUsage ResourceUsage `json:"resourceUsage,omitempty"`
// AgentStatus is an array of current observed status, each corresponding to one member agent running in the member cluster.
// +optional
AgentStatus []AgentStatus `json:"agentStatus,omitempty"`
}
//+kubebuilder:object:root=true
// InternalMemberClusterList contains a list of InternalMemberCluster.
type InternalMemberClusterList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []InternalMemberCluster `json:"items"`
}
// SetConditionsWithType is used to add condition to AgentStatus for a given agentType.
func (m *InternalMemberCluster) SetConditionsWithType(agentType AgentType, conditions ...metav1.Condition) {
desiredAgentStatus := m.GetAgentStatus(agentType)
for _, c := range conditions {
meta.SetStatusCondition(&desiredAgentStatus.Conditions, c)
}
}
// GetConditionWithType is used to retrieve the desired condition from AgentStatus for given agentType
func (m *InternalMemberCluster) GetConditionWithType(agentType AgentType, conditionType string) *metav1.Condition {
var desiredAgentStatus AgentStatus
for _, agentStatus := range m.Status.AgentStatus {
if agentType == agentStatus.Type {
desiredAgentStatus = agentStatus
}
}
if desiredAgentStatus.Type == agentType {
return meta.FindStatusCondition(desiredAgentStatus.Conditions, conditionType)
}
return nil
}
// GetAgentStatus is used to retrieve agent status from internal member cluster,
// if it doesn't exist it creates the expected agent status and returns it.
func (m *InternalMemberCluster) GetAgentStatus(agentType AgentType) *AgentStatus {
for i := range m.Status.AgentStatus {
if m.Status.AgentStatus[i].Type == agentType {
return &m.Status.AgentStatus[i]
}
}
agentStatus := AgentStatus{
Type: agentType,
Conditions: []metav1.Condition{},
}
m.Status.AgentStatus = append(m.Status.AgentStatus, agentStatus)
return &m.Status.AgentStatus[len(m.Status.AgentStatus)-1]
}
func init() {
SchemeBuilder.Register(&InternalMemberCluster{}, &InternalMemberClusterList{})
}