mirror of
https://gitee.com/XM-GO/PandaX.git
synced 2026-04-23 19:08:35 +08:00
305 lines
13 KiB
Go
305 lines
13 KiB
Go
package controller
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
apps "k8s.io/api/apps/v1"
|
|
batch "k8s.io/api/batch/v1"
|
|
v1 "k8s.io/api/core/v1"
|
|
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
client "k8s.io/client-go/kubernetes"
|
|
"pandax/apps/devops/entity/k8s"
|
|
k8scommon "pandax/apps/devops/services/k8s/common"
|
|
"pandax/apps/devops/services/k8s/event"
|
|
"strings"
|
|
)
|
|
|
|
// ResourceOwner is an structure representing resource owner, it may be Replication Controller,
|
|
// Daemon Set, Job etc.
|
|
type ResourceOwner struct {
|
|
ObjectMeta k8s.ObjectMeta `json:"objectMeta"`
|
|
TypeMeta k8s.TypeMeta `json:"typeMeta"`
|
|
Pods k8scommon.PodInfo `json:"pods"`
|
|
ContainerImages []string `json:"containerImages"`
|
|
InitContainerImages []string `json:"initContainerImages"`
|
|
}
|
|
|
|
// LogSources is a structure that represents all log files (all combinations of pods and container)
|
|
// from a higher level controller (such as ReplicaSet).
|
|
type LogSources struct {
|
|
ContainerNames []string `json:"containerNames"`
|
|
InitContainerNames []string `json:"initContainerNames"`
|
|
PodNames []string `json:"podNames"`
|
|
}
|
|
|
|
// ResourceController is an interface, that allows to perform operations on resource controller. To
|
|
// instantiate it use NewResourceController and pass object reference to it. It may be extended to
|
|
// provide more detailed set of functions.
|
|
type ResourceController interface {
|
|
// UID returns UID of controlled resource.
|
|
UID() types.UID
|
|
// Get is a method, that returns ResourceOwner object.
|
|
Get(allPods []v1.Pod, allEvents []v1.Event) ResourceOwner
|
|
// Returns all log sources of controlled resource (e.g. a list of containers and pods for a replica set).
|
|
GetLogSources(allPods []v1.Pod) LogSources
|
|
}
|
|
|
|
// NewResourceController creates instance of ResourceController based on given reference. It allows
|
|
// to convert owner/created by references to real objects.
|
|
func NewResourceController(ref meta.OwnerReference, namespace string, client client.Interface) (
|
|
ResourceController, error) {
|
|
switch strings.ToLower(ref.Kind) {
|
|
case k8s.ResourceKindJob:
|
|
job, err := client.BatchV1().Jobs(namespace).Get(context.TODO(), ref.Name, meta.GetOptions{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return JobController(*job), nil
|
|
case k8s.ResourceKindPod:
|
|
pod, err := client.CoreV1().Pods(namespace).Get(context.TODO(), ref.Name, meta.GetOptions{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return PodController(*pod), nil
|
|
case k8s.ResourceKindReplicaSet:
|
|
rs, err := client.AppsV1().ReplicaSets(namespace).Get(context.TODO(), ref.Name, meta.GetOptions{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return ReplicaSetController(*rs), nil
|
|
case k8s.ResourceKindReplicationController:
|
|
rc, err := client.CoreV1().ReplicationControllers(namespace).Get(context.TODO(), ref.Name, meta.GetOptions{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return ReplicationControllerController(*rc), nil
|
|
case k8s.ResourceKindDaemonSet:
|
|
ds, err := client.AppsV1().DaemonSets(namespace).Get(context.TODO(), ref.Name, meta.GetOptions{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return DaemonSetController(*ds), nil
|
|
case k8s.ResourceKindStatefulSet:
|
|
ss, err := client.AppsV1().StatefulSets(namespace).Get(context.TODO(), ref.Name, meta.GetOptions{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return StatefulSetController(*ss), nil
|
|
default:
|
|
return nil, fmt.Errorf("unknown reference kind: %s", ref.Kind)
|
|
}
|
|
}
|
|
|
|
// JobController is an alias-type for Kubernetes API Job type. It allows to provide custom set of
|
|
// functions for already existing type.
|
|
type JobController batch.Job
|
|
|
|
// Get is an implementation of Get method from ResourceController interface.
|
|
func (self JobController) Get(allPods []v1.Pod, allEvents []v1.Event) ResourceOwner {
|
|
matchingPods := k8scommon.FilterPodsForJob(batch.Job(self), allPods)
|
|
podInfo := k8scommon.GetPodInfo(self.Status.Active, self.Spec.Completions, matchingPods)
|
|
podInfo.Warnings = event.GetPodsEventWarnings(allEvents, matchingPods)
|
|
|
|
return ResourceOwner{
|
|
TypeMeta: k8s.NewTypeMeta(k8s.ResourceKindJob),
|
|
ObjectMeta: k8s.NewObjectMeta(self.ObjectMeta),
|
|
Pods: podInfo,
|
|
ContainerImages: k8scommon.GetContainerImages(&self.Spec.Template.Spec),
|
|
InitContainerImages: k8scommon.GetInitContainerImages(&self.Spec.Template.Spec),
|
|
}
|
|
}
|
|
|
|
// UID is an implementation of UID method from ResourceController interface.
|
|
func (self JobController) UID() types.UID {
|
|
return batch.Job(self).UID
|
|
}
|
|
|
|
// GetLogSources is an implementation of the GetLogSources method from ResourceController interface.
|
|
func (self JobController) GetLogSources(allPods []v1.Pod) LogSources {
|
|
controlledPods := k8scommon.FilterPodsForJob(batch.Job(self), allPods)
|
|
return LogSources{
|
|
PodNames: getPodNames(controlledPods),
|
|
ContainerNames: k8scommon.GetContainerNames(&self.Spec.Template.Spec),
|
|
InitContainerNames: k8scommon.GetInitContainerNames(&self.Spec.Template.Spec),
|
|
}
|
|
}
|
|
|
|
type PodController v1.Pod
|
|
|
|
// Get is an implementation of Get method from ResourceController interface.
|
|
func (self PodController) Get(allPods []v1.Pod, allEvents []v1.Event) ResourceOwner {
|
|
matchingPods := k8scommon.FilterPodsByControllerRef(&self, allPods)
|
|
podInfo := k8scommon.GetPodInfo(int32(len(matchingPods)), nil, matchingPods) // Pods should not desire any Pods
|
|
podInfo.Warnings = event.GetPodsEventWarnings(allEvents, matchingPods)
|
|
|
|
return ResourceOwner{
|
|
TypeMeta: k8s.NewTypeMeta(k8s.ResourceKindPod),
|
|
ObjectMeta: k8s.NewObjectMeta(self.ObjectMeta),
|
|
Pods: podInfo,
|
|
ContainerImages: k8scommon.GetNonduplicateContainerImages(matchingPods),
|
|
InitContainerImages: k8scommon.GetNonduplicateInitContainerImages(matchingPods),
|
|
}
|
|
}
|
|
|
|
// UID is an implementation of UID method from ResourceController interface.
|
|
func (self PodController) UID() types.UID {
|
|
return v1.Pod(self).UID
|
|
}
|
|
|
|
// GetLogSources is an implementation of the GetLogSources method from ResourceController interface.
|
|
func (self PodController) GetLogSources(allPods []v1.Pod) LogSources {
|
|
controlledPods := k8scommon.FilterPodsByControllerRef(&self, allPods)
|
|
return LogSources{
|
|
PodNames: getPodNames(controlledPods),
|
|
ContainerNames: k8scommon.GetNonduplicateContainerNames(controlledPods),
|
|
InitContainerNames: k8scommon.GetNonduplicateInitContainerNames(controlledPods),
|
|
}
|
|
}
|
|
|
|
// ReplicaSetController is an alias-type for Kubernetes API Replica Set type. It allows to provide
|
|
// custom set of functions for already existing type.
|
|
type ReplicaSetController apps.ReplicaSet
|
|
|
|
// Get is an implementation of Get method from ResourceController interface.
|
|
func (self ReplicaSetController) Get(allPods []v1.Pod, allEvents []v1.Event) ResourceOwner {
|
|
matchingPods := k8scommon.FilterPodsByControllerRef(&self, allPods)
|
|
podInfo := k8scommon.GetPodInfo(self.Status.Replicas, self.Spec.Replicas, matchingPods)
|
|
podInfo.Warnings = event.GetPodsEventWarnings(allEvents, matchingPods)
|
|
|
|
return ResourceOwner{
|
|
TypeMeta: k8s.NewTypeMeta(k8s.ResourceKindReplicaSet),
|
|
ObjectMeta: k8s.NewObjectMeta(self.ObjectMeta),
|
|
Pods: podInfo,
|
|
ContainerImages: k8scommon.GetContainerImages(&self.Spec.Template.Spec),
|
|
InitContainerImages: k8scommon.GetInitContainerImages(&self.Spec.Template.Spec),
|
|
}
|
|
}
|
|
|
|
// UID is an implementation of UID method from ResourceController interface.
|
|
func (self ReplicaSetController) UID() types.UID {
|
|
return apps.ReplicaSet(self).UID
|
|
}
|
|
|
|
// GetLogSources is an implementation of the GetLogSources method from ResourceController interface.
|
|
func (self ReplicaSetController) GetLogSources(allPods []v1.Pod) LogSources {
|
|
controlledPods := k8scommon.FilterPodsByControllerRef(&self, allPods)
|
|
return LogSources{
|
|
PodNames: getPodNames(controlledPods),
|
|
ContainerNames: k8scommon.GetContainerNames(&self.Spec.Template.Spec),
|
|
InitContainerNames: k8scommon.GetInitContainerNames(&self.Spec.Template.Spec),
|
|
}
|
|
}
|
|
|
|
// ReplicationControllerController is an alias-type for Kubernetes API Replication Controller type.
|
|
// It allows to provide custom set of functions for already existing type.
|
|
type ReplicationControllerController v1.ReplicationController
|
|
|
|
// Get is an implementation of Get method from ResourceController interface.
|
|
func (self ReplicationControllerController) Get(allPods []v1.Pod,
|
|
allEvents []v1.Event) ResourceOwner {
|
|
matchingPods := k8scommon.FilterPodsByControllerRef(&self, allPods)
|
|
podInfo := k8scommon.GetPodInfo(self.Status.Replicas, self.Spec.Replicas, matchingPods)
|
|
podInfo.Warnings = event.GetPodsEventWarnings(allEvents, matchingPods)
|
|
|
|
return ResourceOwner{
|
|
TypeMeta: k8s.NewTypeMeta(k8s.ResourceKindReplicationController),
|
|
ObjectMeta: k8s.NewObjectMeta(self.ObjectMeta),
|
|
Pods: podInfo,
|
|
ContainerImages: k8scommon.GetContainerImages(&self.Spec.Template.Spec),
|
|
InitContainerImages: k8scommon.GetInitContainerImages(&self.Spec.Template.Spec),
|
|
}
|
|
}
|
|
|
|
// UID is an implementation of UID method from ResourceController interface.
|
|
func (self ReplicationControllerController) UID() types.UID {
|
|
return v1.ReplicationController(self).UID
|
|
}
|
|
|
|
// GetLogSources is an implementation of the GetLogSources method from ResourceController interface.
|
|
func (self ReplicationControllerController) GetLogSources(allPods []v1.Pod) LogSources {
|
|
controlledPods := k8scommon.FilterPodsByControllerRef(&self, allPods)
|
|
return LogSources{
|
|
PodNames: getPodNames(controlledPods),
|
|
ContainerNames: k8scommon.GetContainerNames(&self.Spec.Template.Spec),
|
|
InitContainerNames: k8scommon.GetInitContainerNames(&self.Spec.Template.Spec),
|
|
}
|
|
}
|
|
|
|
// DaemonSetController is an alias-type for Kubernetes API Daemon Set type. It allows to provide
|
|
// custom set of functions for already existing type.
|
|
type DaemonSetController apps.DaemonSet
|
|
|
|
// Get is an implementation of Get method from ResourceController interface.
|
|
func (self DaemonSetController) Get(allPods []v1.Pod, allEvents []v1.Event) ResourceOwner {
|
|
matchingPods := k8scommon.FilterPodsByControllerRef(&self, allPods)
|
|
podInfo := k8scommon.GetPodInfo(self.Status.CurrentNumberScheduled,
|
|
&self.Status.DesiredNumberScheduled, matchingPods)
|
|
podInfo.Warnings = event.GetPodsEventWarnings(allEvents, matchingPods)
|
|
|
|
return ResourceOwner{
|
|
TypeMeta: k8s.NewTypeMeta(k8s.ResourceKindDaemonSet),
|
|
ObjectMeta: k8s.NewObjectMeta(self.ObjectMeta),
|
|
Pods: podInfo,
|
|
ContainerImages: k8scommon.GetContainerImages(&self.Spec.Template.Spec),
|
|
InitContainerImages: k8scommon.GetInitContainerImages(&self.Spec.Template.Spec),
|
|
}
|
|
}
|
|
|
|
// UID is an implementation of UID method from ResourceController interface.
|
|
func (self DaemonSetController) UID() types.UID {
|
|
return apps.DaemonSet(self).UID
|
|
}
|
|
|
|
// GetLogSources is an implementation of the GetLogSources method from ResourceController interface.
|
|
func (self DaemonSetController) GetLogSources(allPods []v1.Pod) LogSources {
|
|
controlledPods := k8scommon.FilterPodsByControllerRef(&self, allPods)
|
|
return LogSources{
|
|
PodNames: getPodNames(controlledPods),
|
|
ContainerNames: k8scommon.GetContainerNames(&self.Spec.Template.Spec),
|
|
InitContainerNames: k8scommon.GetInitContainerNames(&self.Spec.Template.Spec),
|
|
}
|
|
}
|
|
|
|
// StatefulSetController is an alias-type for Kubernetes API Stateful Set type. It allows to provide
|
|
// custom set of functions for already existing type.
|
|
type StatefulSetController apps.StatefulSet
|
|
|
|
// Get is an implementation of Get method from ResourceController interface.
|
|
func (self StatefulSetController) Get(allPods []v1.Pod, allEvents []v1.Event) ResourceOwner {
|
|
matchingPods := k8scommon.FilterPodsByControllerRef(&self, allPods)
|
|
podInfo := k8scommon.GetPodInfo(self.Status.Replicas, self.Spec.Replicas, matchingPods)
|
|
podInfo.Warnings = event.GetPodsEventWarnings(allEvents, matchingPods)
|
|
|
|
return ResourceOwner{
|
|
TypeMeta: k8s.NewTypeMeta(k8s.ResourceKindStatefulSet),
|
|
ObjectMeta: k8s.NewObjectMeta(self.ObjectMeta),
|
|
Pods: podInfo,
|
|
ContainerImages: k8scommon.GetContainerImages(&self.Spec.Template.Spec),
|
|
InitContainerImages: k8scommon.GetInitContainerImages(&self.Spec.Template.Spec),
|
|
}
|
|
}
|
|
|
|
// UID is an implementation of UID method from ResourceController interface.
|
|
func (self StatefulSetController) UID() types.UID {
|
|
return apps.StatefulSet(self).UID
|
|
}
|
|
|
|
// GetLogSources is an implementation of the GetLogSources method from ResourceController interface.
|
|
func (self StatefulSetController) GetLogSources(allPods []v1.Pod) LogSources {
|
|
controlledPods := k8scommon.FilterPodsByControllerRef(&self, allPods)
|
|
return LogSources{
|
|
PodNames: getPodNames(controlledPods),
|
|
ContainerNames: k8scommon.GetContainerNames(&self.Spec.Template.Spec),
|
|
InitContainerNames: k8scommon.GetInitContainerNames(&self.Spec.Template.Spec),
|
|
}
|
|
}
|
|
|
|
func getPodNames(pods []v1.Pod) []string {
|
|
names := make([]string, 0)
|
|
for _, pod := range pods {
|
|
names = append(names, pod.Name)
|
|
}
|
|
return names
|
|
}
|