Skip to content

Commit

Permalink
Backup implementation part 2
Browse files Browse the repository at this point in the history
* install velero via flux rather than code
* adjust roles for the velero chart
* remove unnecessary controller values
* rename Backup to ManagementBackup
* remove Oneshot parameter from the Spec
* remove unused types
* manage schedules in the ctrl instead of velero
* new source runner for schedules
* collect the required velero backup spec for the whole backup
* label Credential references (clusterIdentities) in order to include them in backup
* backup validation webhook
* amend backup controller logic with better objects handling
* fix bug in providertemplates ctrl when ownerreferences are being updated but requeue is not set
* add custom plugins set via mgmt spec
* rename k0smotron related provider labels to the correct ones from the k0sproject
  • Loading branch information
zerospiel committed Jan 17, 2025
1 parent 3429f91 commit d621663
Show file tree
Hide file tree
Showing 91 changed files with 1,732 additions and 1,290 deletions.
5 changes: 4 additions & 1 deletion PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@ resources:
controller: true
domain: k0rdent.mirantis.com
group: k0rdent.mirantis.com
kind: Backup
kind: ManagementBackup
path: github.com/K0rdent/kcm/api/v1alpha1
version: v1alpha1
webhooks:
validation: true
webhookVersion: v1
version: "3"
77 changes: 0 additions & 77 deletions api/v1alpha1/backup_types.go

This file was deleted.

23 changes: 23 additions & 0 deletions api/v1alpha1/indexers.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func SetupIndexers(ctx context.Context, mgr ctrl.Manager) error {
setupClusterTemplateProvidersIndexer,
setupMultiClusterServiceServicesIndexer,
setupOwnerReferenceIndexers,
setupManagementBackupScheduledIndexer,
} {
merr = errors.Join(merr, f(ctx, mgr))
}
Expand Down Expand Up @@ -237,3 +238,25 @@ func extractOwnerReferences(rawObj client.Object) []string {
}
return owners
}

// management backup indexers

// ManagementBackupScheduledIndexKey indexer field name to extract only [ManagementBackup] objects
// that meant to be scheduled.
const ManagementBackupScheduledIndexKey = "k0rdent.scheduled-backup"

func setupManagementBackupScheduledIndexer(ctx context.Context, mgr ctrl.Manager) error {
return mgr.GetFieldIndexer().IndexField(ctx, &ManagementBackup{}, ManagementBackupScheduledIndexKey, func(o client.Object) []string {
mb, ok := o.(*ManagementBackup)
if !ok {
return nil
}

v, ok := mb.Annotations[ScheduleBackupAnnotation]
if !ok {
return nil
}

return []string{v}
})
}
98 changes: 98 additions & 0 deletions api/v1alpha1/management_backup_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright 2024
//
// 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 (
"strconv"
"time"

velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
// Name to label most of the KCM-related components.
// Mostly utilized by the backup feature.
GenericComponentNameLabel = "k0rdent.mirantis.com/component"
// Component label value for the KCM-related components.
GenericComponentLabelValueKCM = "kcm"

// ScheduleBackupAnnotation is an annotation for ease the listing
// of [ManagementBackup]. Indicates that the type of the object is schedule.
ScheduleBackupAnnotation = "k0rdent.mirantis.com/schedule"
)

// ManagementBackupSpec defines the desired state of ManagementBackup
type ManagementBackupSpec struct{}

// ManagementBackupStatus defines the observed state of ManagementBackup
type ManagementBackupStatus struct {
// NextAttempt indicates the time when the next backup will be created.
// Always absent for a single [ManagementBackup].
NextAttempt *metav1.Time `json:"nextAttempt,omitempty"`
// Time of the most recently created [github.com/vmware-tanzu/velero/pkg/apis/velero/v1.Backup].
LastBackupTime *metav1.Time `json:"lastBackupTime,omitempty"`
// Most recently [github.com/vmware-tanzu/velero/pkg/apis/velero/v1.Backup] that has been created.
LastBackup *velerov1.BackupStatus `json:"lastBackup,omitempty"`
// Name of most recently created [github.com/vmware-tanzu/velero/pkg/apis/velero/v1.Backup].
LastBackupName string `json:"lastBackupName,omitempty"`
// Paused indicates if the schedule is currently paused.
Paused bool `json:"paused,omitempty"`
}

// IsSchedule checks if an instance of [ManagementBackup] is schedulable.
func (s *ManagementBackup) IsSchedule() bool {
if _, err := strconv.ParseBool(s.Annotations[ScheduleBackupAnnotation]); err == nil {
return true
}

return false
}

// TimestampedBackupName returns the backup name related to scheduled [ManagementBackup] based on the given timestamp.
func (s *ManagementBackup) TimestampedBackupName(timestamp time.Time) string {
return s.Name + "-" + timestamp.Format("20060102150405")
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope=Cluster,shortName=kcmbackup;mgmtbackup
// +kubebuilder:printcolumn:name="LastBackupStatus",type=string,JSONPath=`.status.lastBackup.phase`,description="Status of last backup run",priority=0
// +kubebuilder:printcolumn:name="NextBackup",type=string,JSONPath=`.status.nextAttempt`,description="Next scheduled attempt to back up",priority=0
// +kubebuilder:printcolumn:name="SinceLastBackup",type=date,JSONPath=`.status.lastBackupTime`,description="Time elapsed since last backup run",priority=1
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`,description="Time elapsed since object creation",priority=0
// +kubebuilder:printcolumn:name="Paused",type=boolean,JSONPath=`.status.paused`,description="Schedule is on pause",priority=1

// ManagementBackup is the Schema for the managementbackups API
type ManagementBackup struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec ManagementBackupSpec `json:"spec,omitempty"`
Status ManagementBackupStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// ManagementBackupList contains a list of ManagementBackup
type ManagementBackupList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ManagementBackup `json:"items"`
}

func init() {
SchemeBuilder.Register(&ManagementBackup{}, &ManagementBackupList{})
}
15 changes: 7 additions & 8 deletions api/v1alpha1/management_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type ManagementSpec struct {
// Providers is the list of supported CAPI providers.
Providers []Provider `json:"providers,omitempty"`

Backup ManagementBackup `json:"backup,omitempty"`
Backup Backup `json:"backup,omitempty"`
}

// Core represents a structure describing core Management components.
Expand All @@ -55,15 +55,14 @@ type Core struct {
CAPI Component `json:"capi,omitempty"`
}

// ManagementBackup enables a feature to backup KCM objects into a cloud.
type ManagementBackup struct {
// Schedule is a Cron expression defining when to run the scheduled Backup.
// Default value is to backup every 6 hours.
// Backup enables a feature to backup KCM objects into a cloud.
type Backup struct {
// Schedule is a Cron expression defining when to run the scheduled [ManagementBackup].
// Default value is to backup at minute 0 past every 6th hour (0 */6 * * *).
Schedule string `json:"schedule,omitempty"`

// Flag to indicate whether the backup feature is enabled.
// If set to true, [Velero] platform will be installed.
// If set to false, creation or modification of Backups/Restores will be blocked.
// Flag to indicate whether the management cluster backup feature is enabled.
// The backup is done using [Velero].
//
// [Velero]: https://velero.io
Enabled bool `json:"enabled,omitempty"`
Expand Down
7 changes: 2 additions & 5 deletions api/v1alpha1/templates_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,10 @@ import (
helmcontrollerv2 "github.com/fluxcd/helm-controller/api/v2"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
clusterapiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1"
)

const (
// ChartAnnotationProviderName is the annotation set on components in a Template.
// This annotations allows to identify all the components belonging to a provider.
ChartAnnotationProviderName = "cluster.x-k8s.io/provider"

chartAnnoCAPIPrefix = "cluster.x-k8s.io/"

DefaultRepoName = "kcm-templates"
Expand Down Expand Up @@ -103,7 +100,7 @@ func getProvidersList(providers Providers, annotations map[string]string) Provid
return slices.Compact(res)
}

providersFromAnno := annotations[ChartAnnotationProviderName]
providersFromAnno := annotations[clusterapiv1beta1.ProviderNameLabel]
if len(providersFromAnno) == 0 {
return Providers{}
}
Expand Down
Loading

0 comments on commit d621663

Please sign in to comment.