Skip to content

Commit

Permalink
Merge pull request #179 from AmitRoushan/resource-based-backup-restore
Browse files Browse the repository at this point in the history
[Metadata] Plugin based backup/restore
  • Loading branch information
skdwriting authored Jun 13, 2023
2 parents 1407b86 + 1d5599d commit 312eaae
Show file tree
Hide file tree
Showing 222 changed files with 25,703 additions and 11,809 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
*.out

# Dependency directories (remove the comment below to include it)
# vendor/
vendor/
_output/
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Kahu is part of SODA Container Data Management(CDM). Kahu provides seamless back


## High Level Architecture
![Kahu High Level Design](https://github.com/soda-cdm/documentation/blob/main/kahu/resources/Level_0_Arch.png)
![Kahu High Level Design](docs/design/HighLevelDesign.jpg)

For more details, please refer [Design Doc](https://github.com/soda-cdm/documentation/blob/main/kahu/design_spec.md)

Expand All @@ -20,6 +20,11 @@ Please take a look at the following documents to get started
4. [API Reference](https://soda-cdm.github.io/kahu/)
5. [Development Guide](https://github.com/soda-cdm/documentation/blob/main/kahu/development_guide.md)

## Biweekly Meetup

- :speaking_head: [Zoom Link](https://us02web.zoom.us/j/86039856379?pwd=MW5MNlh0MVNSbzNGNFhoNldXWmk4Zz09)
- :page_facing_up: Minutes: [Document](https://docs.google.com/document/d/1dP_i9TsiSfBvqoDwBwn4vl2xftanfSnL/edit)

## Community
Please join [SODA Slack](https://sodafoundation.io/slack) and channel #soda-cdm.

Expand Down
51 changes: 12 additions & 39 deletions apis/kahu/v1beta1/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope=Cluster
// +kubebuilder:printcolumn:name="Stage",type=string,JSONPath=`.status.stage`
// +kubebuilder:printcolumn:name="State",type=string,JSONPath=`.status.state`
// +kubebuilder:printcolumn:name="MetadataLocation",type=string,JSONPath=`.spec.metadataLocation`
// +kubebuilder:printcolumn:name="VolumeBackupLocations",type=string,JSONPath=`.spec.volumeBackupLocations`
Expand All @@ -50,6 +49,7 @@ type BackupSpec struct {

// ReclaimPolicy tells about reclamation of the backup. It can be either delete or retain
// +optional
// +kubebuilder:default=Delete
ReclaimPolicy ReclaimPolicyType `json:"reclaimPolicy,omitempty"`

// Hook is pre or post operations which should be executed during backup
Expand Down Expand Up @@ -185,21 +185,25 @@ const (
)

// ReclaimPolicy tells about reclamation of the backup. It can be either delete or retain
type ReclaimPolicyType struct {
// +kubebuilder:validation:Enum=Delete;Retain
type ReclaimPolicyType string

const (
// +optional
ReclaimPolicyDelete string `json:"reclaimPolicyDelete,omitempty"`
ReclaimPolicyDelete ReclaimPolicyType = "Delete"

// +optional
ReclaimPolicyRetain string `json:"reclaimPolicyRetain,omitempty"`
}
ReclaimPolicyRetain ReclaimPolicyType = "Retain"
)

// +kubebuilder:validation:Enum=Pending;Processing;Completed
// +kubebuilder:validation:Enum=Pending;Processing;Failed;Completed
// ResourceStatus is a state a resource during backup
type ResourceStatus string

const (
Pending ResourceStatus = "Pending"
Processing ResourceStatus = "Processing"
Failed ResourceStatus = "Failed"
Completed ResourceStatus = "Completed"
)

Expand All @@ -217,42 +221,18 @@ type BackupResource struct {

// Status is a state of the resource
// +optional
// +kubebuilder:default=Pending
Status ResourceStatus `json:"status,omitempty"`
}

// +kubebuilder:validation:Enum=Initial;PreHook;Resources;Volumes;PostHook;Finished
// BackupStage is a stage of backup
type BackupStage string

// +kubebuilder:validation:Enum=New;Validating;Processing;Completed;Deleting;Failed
// BackupState is a state in backup phase
type BackupState string

const (
// BackupStageInitial indicates that current backup object is New
BackupStageInitial BackupStage = "Initial"

// BackupStagePreHook indicates that current backup object is pre hook
BackupStagePreHook BackupStage = "PreHook"

// BackupStageResources indicates that metadata are getting backup
BackupStageResources BackupStage = "Resources"

// BackupStageVolumes indicates that volume are getting backup
BackupStageVolumes BackupStage = "Volumes"

// BackupStagePostHook indicates that current backup object is post hook
BackupStagePostHook BackupStage = "PostHook"

// BackupStageFinished indicates that backup is successfully completed
BackupStageFinished BackupStage = "Finished"

// BackupStateNew indicates that backup object in initial state
BackupStateNew BackupState = "New"

// BackupStateValidating indicates that backup object is under validation
BackupStateValidating BackupState = "Validating"

// BackupStateFailed indicates that backup object has validation issues
BackupStateFailed BackupState = "Failed"

Expand All @@ -267,18 +247,11 @@ const (
)

type BackupStatus struct {
// Stage is the current phase of the backup
// +optional
Stage BackupStage `json:"stage,omitempty"`

// State is the current state in backup
// +kubebuilder:default=New
// +optional
State BackupState `json:"state,omitempty"`

// LastBackup defines the last backup time
// +optional
LastBackup *metav1.Time `json:"lastBackup,omitempty"`

// ValidationErrors is a list of erros which are founded during validation of backup spec
// +optional
ValidationErrors []string `json:"validationErrors,omitempty"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
// set annotation to set default backup location for specific provider
AnnDefaultBackupLocation = "kahu.io/defaultBackupLocation"
)

// BackupLocationSpec defines the desired state of BackupLocation
type BackupLocationSpec struct {
// ProviderName is a 3rd party driver which inernally connect to respective storage
Expand All @@ -30,12 +35,15 @@ type BackupLocationSpec struct {
// Config is a dictonary which may contains specific details, like secret key, password etc
// +optional
Config map[string]string `json:"config,omitempty"`

// +optional
Location *LocationSpec `json:"location,omitempty"`
}

// +genclient
// +genclient:nonNamespaced
// +genclient:skipVerbs=update,patch
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope=Cluster,shortName="bl"
// +kubebuilder:printcolumn:name="Provider",type=string,JSONPath=`.spec.providerName`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
Expand All @@ -49,6 +57,15 @@ type BackupLocation struct {

// +optional
Spec BackupLocationSpec `json:"spec,omitempty"`

// +optional
Status BackupLocationStatus `json:"status,omitempty"`
}

type BackupLocationStatus struct {
// Active status indicate state of the backup location.
// +kubebuilder:default=false
Active bool `json:"active,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand All @@ -62,3 +79,25 @@ type BackupLocationList struct {
// +optional
Items []BackupLocation `json:"items"`
}

// +kubebuilder:validation:Enum=PersistentVolumeClaim;Secret
type LocationSupportKind string

const (
PVCLocationSupport LocationSupportKind = "PersistentVolumeClaim"
SecretLocationSupport LocationSupportKind = "Secret"
)

type LocationSpec struct {
// +required
Path *string `json:"path,omitempty"`
// +required
SourceRef *Source `json:"sourceRef,omitempty"`
}

type Source struct {
// +required
Name *string `json:"name,omitempty"`
// +required
Kind LocationSupportKind `json:"kind,omitempty"`
}
15 changes: 15 additions & 0 deletions apis/kahu/v1beta1/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1beta1

import (
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down Expand Up @@ -46,3 +47,17 @@ type ResourceSelector struct {

Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,4,opt,name=selector"`
}

func (in *BackupResource) ResourceID() string {
if in.Namespace == "" {
return fmt.Sprintf("%s.%s/%s", in.Kind, in.APIVersion, in.ResourceName)
}
return fmt.Sprintf("%s.%s/%s/%s", in.Kind, in.APIVersion, in.Namespace, in.ResourceName)
}

func (in *RestoreResource) ResourceID() string {
if in.Namespace == "" {
return fmt.Sprintf("%s.%s/%s", in.Kind, in.APIVersion, in.ResourceName)
}
return fmt.Sprintf("%s.%s/%s/%s", in.Kind, in.APIVersion, in.Namespace, in.ResourceName)
}
13 changes: 10 additions & 3 deletions apis/kahu/v1beta1/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ const (
ProviderStateUnavailable ProviderState = "Unavailable"
)

const (
AnnDefaultVolumeProvider = "kahu.io/defaultVolumeProvider"
)

// ProviderType is the type of Provider.
// +kubebuilder:validation:Enum=MetadataProvider;VolumeProvider
// +kubebuilder:default=MetadataProvider
Expand Down Expand Up @@ -65,18 +69,21 @@ type ProviderSpec struct {

// Capabilities is the optional set of provider capabilities
// +optional
Capabilities map[string]bool `json:"capabilities,omitempty"`
Capabilities []string `json:"capabilities,omitempty"`

// +optional
SupportedVolumeProvisioners []string `json:"supportedVolumeProvisioners,omitempty"`
SupportedVolumeProvisioner *string `json:"supportedVolumeProvisioner,omitempty"`
}

// ProviderStatus defines the observed state of Provider
type ProviderStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file

// +kubebuilder:default=Available
// +optional
State ProviderState `json:"state,omitempty"`

Message string `json:"message,omitempty"`
}

// +genclient
Expand Down
121 changes: 121 additions & 0 deletions apis/kahu/v1beta1/providerregistration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
Copyright 2022 The SODA Authors.
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 v1beta1

import (
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope=Cluster,shortName="pr"
// +kubebuilder:printcolumn:name="Provider",type=string,JSONPath=`.spec.providerName`
// +kubebuilder:printcolumn:name="Active",type=string,JSONPath=`.status.active`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
type ProviderRegistration struct {
metav1.TypeMeta `json:",inline"`

// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`

// +optional
Spec RegistrationSpec `json:"spec,omitempty"`

// +optional
Status RegistrationStatus `json:"status,omitempty"`
}

type RegistrationStatus struct {
// Active status indicate state of the Plugin.
Active bool `json:"active,omitempty"`
}

// Plugin specifications
type RegistrationSpec struct {
// +required
ProviderName *string `json:"providerName,omitempty"`

// +required
// +kubebuilder:default=ResourceBackup
ProviderType RegistrationType `json:"providerType,omitempty"`

// +required
Version *string `json:"version,omitempty"`

// +optional
Parameters map[string]string `json:"parameters,omitempty"`

// Capabilities is the optional set of provider capabilities
// +optional
Capabilities []string `json:"capabilities,omitempty"`

// +optional
SupportedVolumeProvisioner *string `json:"supportedVolumeProvisioner,omitempty"`

// +required
Template *v1.PodTemplateSpec `json:"template,omitempty"`

// +optional
Lifecycle `json:"lifecycle,omitempty"`
}

// +kubebuilder:validation:Enum=VOLUME_BACKUP_NEED_SNAPSHOT;VOLUME_BACKUP_NEED_VOLUME
type Support string

const (
VolumeBackupNeedSnapshotSupport Support = "VOLUME_BACKUP_NEED_SNAPSHOT"
VolumeBackupNeedVolumeSupport Support = "VOLUME_BACKUP_NEED_VOLUME"
)

// +kubebuilder:validation:Enum=ResourceBackup;VolumeBackup
type RegistrationType string

const (
// Backup location
ResourceBackup RegistrationType = "ResourceBackup"

// Volume backup/restore
VolumeBackup RegistrationType = "VolumeBackup"
)

type WorkloadKind string

const (
PodWorkloadKind WorkloadKind = "Pod"
DeploymentWorkloadKind WorkloadKind = "Deployment"
)

type Lifecycle struct {
// +kubebuilder:validation:Enum=Pod;Deployment
// +kubebuilder:default=Deployment
Kind WorkloadKind `json:"kind,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

type ProviderRegistrationList struct {
metav1.TypeMeta `json:",inline"`

// +optional
metav1.ListMeta `json:"metadata,omitempty"`

// +optional
Items []ProviderRegistration `json:"items"`
}
Loading

0 comments on commit 312eaae

Please sign in to comment.