Skip to content

Commit

Permalink
Add new status for originCluster reference
Browse files Browse the repository at this point in the history
  • Loading branch information
mallardduck committed Nov 1, 2024
1 parent 5331844 commit 4967e19
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 16 deletions.
3 changes: 3 additions & 0 deletions charts/rancher-backup-crd/templates/backup.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ spec:
type: string
observedGeneration:
type: integer
originCluster:
nullable: true
type: string
storageLocation:
nullable: true
type: string
Expand Down
5 changes: 1 addition & 4 deletions pkg/apis/resources.cattle.io/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ var (
RestoreConditionReady = "Ready"
)

const (
BackupClusterOriginIndex = "field.cattle.io/originClusterId"
)

// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand All @@ -43,6 +39,7 @@ type BackupSpec struct {

type BackupStatus struct {
Conditions []genericcondition.GenericCondition `json:"conditions"`
OriginCluster string `json:"originCluster,omitempty"`
LastSnapshotTS string `json:"lastSnapshotTs"`
NextSnapshotAt string `json:"nextSnapshotAt"`
ObservedGeneration int64 `json:"observedGeneration"`
Expand Down
6 changes: 3 additions & 3 deletions pkg/controllers/backup/cluster_origin.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ func newBackupClusterOriginConditionMeta(controllerClusterID string, backup *v1.
currentInPlaceRestoreCondition: false,
}

originAnnotationValue, ok := backup.GetAnnotations()[v1.BackupClusterOriginIndex]
conditionMeta.hasClusterOriginID = ok && originAnnotationValue != ""
originalValue := backup.Status.OriginCluster
conditionMeta.hasClusterOriginID = originalValue != ""
if conditionMeta.hasClusterOriginID {
conditionMeta.clusterOriginID = originAnnotationValue
conditionMeta.clusterOriginID = originalValue
}

currentOriginConditionString := condition.Cond(v1.BackupConditionClusterOrigin).GetStatus(backup)
Expand Down
14 changes: 5 additions & 9 deletions pkg/controllers/backup/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ type handler struct {
defaultBackupMountPath string
defaultS3BackupLocation *v1.S3ObjectStore
// TODO: rename to kubeSystemNamespaceUID; nit to improve clarity, it's not the string representation nor the NS resource
kubeSystemNS string
kubeSystemNS string
canUseClusterOrigin bool
}

const DefaultRetentionCount = 10
Expand All @@ -66,6 +67,7 @@ func Register(
dynamicClient: dynamicInterface,
defaultBackupMountPath: defaultLocalBackupLocation,
defaultS3BackupLocation: defaultS3,
canUseClusterOrigin: util.VerifyBackupCrdHasClusterStatus(dynamicInterface),
}
if controller.defaultBackupMountPath != "" {
logrus.Infof("Default location for storing backups is %v", controller.defaultBackupMountPath)
Expand Down Expand Up @@ -185,21 +187,15 @@ func (h *handler) OnBackupChange(_ string, backup *v1.Backup) (*v1.Backup, error
}
}

backupAnnotations := backup.GetAnnotations()
if backupAnnotations == nil {
backupAnnotations = map[string]string{}
}
backupAnnotations[v1.BackupClusterOriginIndex] = h.kubeSystemNS
backup.SetAnnotations(backupAnnotations)
_, err = h.backups.Update(backup)

storageLocationType := backup.Status.StorageLocation
updateErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
var err error
backup, err = h.backups.Get(backup.Name, k8sv1.GetOptions{})
if err != nil {
return err
}
// Set the Cluster origin reference on backup
backup.Status.OriginCluster = h.kubeSystemNS
// reset conditions to remove the reconciling condition, because as per kstatus lib its presence is considered an error
backup.Status.Conditions = []genericcondition.GenericCondition{}

Expand Down
48 changes: 48 additions & 0 deletions pkg/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ package util
import (
"context"
"fmt"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/client-go/dynamic"
"os"
"reflect"

v1core "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1"
"github.com/sirupsen/logrus"
k8sv1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/server/options/encryptionconfig"
"k8s.io/apiserver/pkg/storage/value"
Expand Down Expand Up @@ -83,3 +86,48 @@ func FetchClusterUID(namespaces v1core.NamespaceController) (string, error) {

return string(kubesystemNamespace.UID), nil
}

// Define the GroupVersionResource for CRDs
var crdGVR = schema.GroupVersionResource{
Group: "apiextensions.k8s.io",
Version: "v1",
Resource: "customresourcedefinitions",
}

func getCRDDefinition(dynamicClient dynamic.Interface, crdName string) (*unstructured.Unstructured, error) {
crd, err := dynamicClient.Resource(crdGVR).Get(context.TODO(), crdName, metav1.GetOptions{})
if err != nil {
return nil, err
}
return crd, nil
}

func VerifyBackupCrdHasClusterStatus(client dynamic.Interface) bool {
crdName := "backups.resources.cattle.io"

crd, err := getCRDDefinition(client, crdName)
if err != nil {
logrus.Infof("Error fetching CRD: %v", err)
return false
}

// Inspect the status schema, for example
if statusSchema, found, _ := unstructured.NestedMap(
crd.Object,
"spec",
"versions",
"0",
"schema",
"openAPIV3Schema",
"properties",
"status",
"properties",
"originCluster",
); found {
logrus.Debugf("Status schema contains `originCluster` on CRD %s: %v\n", crdName, statusSchema)
return true
}

logrus.Debugf("`originCluster` not found on status schema for CRD %s\n", crdName)
return false
}

0 comments on commit 4967e19

Please sign in to comment.