package helper import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/sets" configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1" "github.com/karmada-io/karmada/pkg/util/lifted" ) // IsPodReady returns true if a pod is ready; false otherwise. func IsPodReady(pod *corev1.Pod) bool { return IsPodReadyConditionTrue(pod.Status) } // IsPodReadyConditionTrue returns true if a pod is ready; false otherwise. func IsPodReadyConditionTrue(status corev1.PodStatus) bool { condition := GetPodReadyCondition(status) return condition != nil && condition.Status == corev1.ConditionTrue } // GetPodReadyCondition extracts the pod ready condition from the given status and returns that. // Returns nil if the condition is not present. func GetPodReadyCondition(status corev1.PodStatus) *corev1.PodCondition { _, condition := GetPodCondition(&status, corev1.PodReady) return condition } // GetPodCondition extracts the provided condition from the given status and returns that. // Returns nil and -1 if the condition is not present, and the index of the located condition. func GetPodCondition(status *corev1.PodStatus, conditionType corev1.PodConditionType) (int, *corev1.PodCondition) { if status == nil { return -1, nil } return GetPodConditionFromList(status.Conditions, conditionType) } // GetPodConditionFromList extracts the provided condition from the given list of condition and // returns the index of the condition and the condition. Returns -1 and nil if the condition is not present. func GetPodConditionFromList(conditions []corev1.PodCondition, conditionType corev1.PodConditionType) (int, *corev1.PodCondition) { if conditions == nil { return -1, nil } for i := range conditions { if conditions[i].Type == conditionType { return i, &conditions[i] } } return -1, nil } // GeneratePodFromTemplateAndNamespace generates a simple pod object from the given podTemplate and namespace, then // returns the generated pod. func GeneratePodFromTemplateAndNamespace(template *corev1.PodTemplateSpec, namespace string) *corev1.Pod { pod := &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Namespace: namespace, }, } pod.Spec = *template.Spec.DeepCopy() return pod } // GetDependenciesFromPodTemplate extracts the dependencies from the given pod and returns that. // returns DependentObjectReferences according to the pod, including ConfigMap, Secret, ServiceAccount and PersistentVolumeClaim. func GetDependenciesFromPodTemplate(podObj *corev1.Pod) ([]configv1alpha1.DependentObjectReference, error) { dependentConfigMaps := getConfigMapNames(podObj) dependentSecrets := getSecretNames(podObj) dependentSas := getServiceAccountNames(podObj) dependentPVCs := getPVCNames(podObj) var dependentObjectRefs []configv1alpha1.DependentObjectReference for cm := range dependentConfigMaps { dependentObjectRefs = append(dependentObjectRefs, configv1alpha1.DependentObjectReference{ APIVersion: "v1", Kind: "ConfigMap", Namespace: podObj.Namespace, Name: cm, }) } for secret := range dependentSecrets { dependentObjectRefs = append(dependentObjectRefs, configv1alpha1.DependentObjectReference{ APIVersion: "v1", Kind: "Secret", Namespace: podObj.Namespace, Name: secret, }) } for sa := range dependentSas { dependentObjectRefs = append(dependentObjectRefs, configv1alpha1.DependentObjectReference{ APIVersion: "v1", Kind: "ServiceAccount", Namespace: podObj.Namespace, Name: sa, }) } for pvc := range dependentPVCs { dependentObjectRefs = append(dependentObjectRefs, configv1alpha1.DependentObjectReference{ APIVersion: "v1", Kind: "PersistentVolumeClaim", Namespace: podObj.Namespace, Name: pvc, }) } return dependentObjectRefs, nil } func getSecretNames(pod *corev1.Pod) sets.Set[string] { result := sets.New[string]() lifted.VisitPodSecretNames(pod, func(name string) bool { result.Insert(name) return true }) return result } func getServiceAccountNames(pod *corev1.Pod) sets.Set[string] { result := sets.New[string]() if pod.Spec.ServiceAccountName != "" && pod.Spec.ServiceAccountName != "default" { result.Insert(pod.Spec.ServiceAccountName) } return result } func getConfigMapNames(pod *corev1.Pod) sets.Set[string] { result := sets.New[string]() lifted.VisitPodConfigmapNames(pod, func(name string) bool { result.Insert(name) return true }) return result } func getPVCNames(pod *corev1.Pod) sets.Set[string] { result := sets.New[string]() for i := range pod.Spec.Volumes { volume := pod.Spec.Volumes[i] if volume.PersistentVolumeClaim != nil { claimName := volume.PersistentVolumeClaim.ClaimName if len(claimName) != 0 { result.Insert(claimName) } } } return result }