Files
kubesphere/pkg/models/revisions/revisions.go
2025-04-30 15:53:51 +08:00

86 lines
3.3 KiB
Go

/*
* Copyright 2024 the KubeSphere Authors.
* Please refer to the LICENSE file in the root directory of the project.
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
*/
package revisions
import (
"context"
"fmt"
appsv1 "k8s.io/api/apps/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
)
type RevisionGetter interface {
GetDeploymentRevision(namespace, name, revision string) (*appsv1.ReplicaSet, error)
GetStatefulSetRevision(namespace, name string, revision int) (*appsv1.ControllerRevision, error)
GetDaemonSetRevision(namespace, name string, revision int) (*appsv1.ControllerRevision, error)
}
type revisionGetter struct {
cache runtimeclient.Reader
}
func NewRevisionGetter(cacheReader runtimeclient.Reader) RevisionGetter {
return &revisionGetter{cache: cacheReader}
}
func (c *revisionGetter) GetDeploymentRevision(namespace, name, revision string) (*appsv1.ReplicaSet, error) {
deployment := &appsv1.Deployment{}
if err := c.cache.Get(context.Background(), types.NamespacedName{Namespace: namespace, Name: name}, deployment); err != nil {
klog.Errorf("get deployment %s failed, reason: %s", name, err)
return nil, err
}
replicaSetList := &appsv1.ReplicaSetList{}
if err := c.cache.List(context.Background(), replicaSetList, client.InNamespace(namespace), client.MatchingLabels(deployment.Spec.Template.Labels)); err != nil {
klog.Errorf("get deployment %s failed, reason: %s", name, err)
return nil, err
}
for _, rs := range replicaSetList.Items {
result := rs.DeepCopy()
if result.Annotations["deployment.kubernetes.io/revision"] == revision {
return result, nil
}
}
return nil, fmt.Errorf("revision not found %v#%v", name, revision)
}
func (c *revisionGetter) GetDaemonSetRevision(namespace, name string, revision int) (*appsv1.ControllerRevision, error) {
daemonSet := &appsv1.DaemonSet{}
if err := c.cache.Get(context.Background(), types.NamespacedName{Namespace: namespace, Name: name}, daemonSet); err != nil {
klog.Errorf("get deployment %s failed, reason: %s", name, err)
return nil, err
}
return c.getControllerRevision(namespace, name, daemonSet.Spec.Template.Labels, revision)
}
func (c *revisionGetter) GetStatefulSetRevision(namespace, name string, revisionInt int) (*appsv1.ControllerRevision, error) {
statefulSet := &appsv1.StatefulSet{}
if err := c.cache.Get(context.Background(), types.NamespacedName{Namespace: namespace, Name: name}, statefulSet); err != nil {
klog.Errorf("get deployment %s failed, reason: %s", name, err)
return nil, err
}
return c.getControllerRevision(namespace, name, statefulSet.Spec.Template.Labels, revisionInt)
}
func (c *revisionGetter) getControllerRevision(namespace, name string, labelMap map[string]string, revision int) (*appsv1.ControllerRevision, error) {
controllerRevisionList := &appsv1.ControllerRevisionList{}
if err := c.cache.List(context.Background(), controllerRevisionList, client.InNamespace(namespace), client.MatchingLabels(labelMap)); err != nil {
return nil, err
}
for _, controllerRevision := range controllerRevisionList.Items {
if controllerRevision.Revision == int64(revision) {
return controllerRevision.DeepCopy(), nil
}
}
return nil, fmt.Errorf("revision not found %v#%v", name, revision)
}