Skip to content

Commit

Permalink
cluster backup and cluster restore were migrated to APIv2 for postgre…
Browse files Browse the repository at this point in the history
…s cassandra redis and opensearch
  • Loading branch information
tengu-alt committed Sep 19, 2023
1 parent 832dc95 commit a56f873
Show file tree
Hide file tree
Showing 33 changed files with 436 additions and 443 deletions.
4 changes: 4 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ resources:
kind: ClusterBackup
path: github.com/instaclustr/operator/apis/clusterresources/v1beta1
version: v1beta1
webhooks:
defaulting: true
validation: true
webhookVersion: v1
- api:
crdVersion: v1
namespaced: true
Expand Down
77 changes: 77 additions & 0 deletions apis/clusterresources/v1beta1/clusterbackup_webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
Copyright 2022.
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/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/webhook"

"github.com/instaclustr/operator/pkg/models"
)

// log is for logging in this package.
var clusterbackuplog = logf.Log.WithName("clusterbackup-resource")

func (r *ClusterBackup) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr).
For(r).
Complete()
}

// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!

//+kubebuilder:webhook:path=/mutate-clusterresources-instaclustr-com-v1beta1-clusterbackup,mutating=true,failurePolicy=fail,sideEffects=None,groups=clusterresources.instaclustr.com,resources=clusterbackups,verbs=create;update,versions=v1beta1,name=mclusterbackup.kb.io,admissionReviewVersions=v1

var _ webhook.Defaulter = &ClusterBackup{}

// Default implements webhook.Defaulter so a webhook will be registered for the type
func (r *ClusterBackup) Default() {
clusterbackuplog.Info("default", "name", r.Name)
}

// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation.
//+kubebuilder:webhook:path=/validate-clusterresources-instaclustr-com-v1beta1-clusterbackup,mutating=false,failurePolicy=fail,sideEffects=None,groups=clusterresources.instaclustr.com,resources=clusterbackups,verbs=create;update,versions=v1beta1,name=vclusterbackup.kb.io,admissionReviewVersions=v1

var _ webhook.Validator = &ClusterBackup{}

// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
func (r *ClusterBackup) ValidateCreate() error {
clusterbackuplog.Info("validate create", "name", r.Name)

_, ok := models.ClusterKindsMap[r.Spec.ClusterKind]
if !ok {
return models.ErrUnsupportedBackupClusterKind
}

return nil
}

// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
func (r *ClusterBackup) ValidateUpdate(old runtime.Object) error {
clusterbackuplog.Info("validate update", "name", r.Name)

return nil
}

// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
func (r *ClusterBackup) ValidateDelete() error {
clusterbackuplog.Info("validate delete", "name", r.Name)

return nil
}
3 changes: 3 additions & 0 deletions apis/clusterresources/v1beta1/webhook_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ var _ = BeforeSuite(func() {
err = (&ExclusionWindow{}).SetupWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())

err = (&ClusterBackup{}).SetupWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())

//+kubebuilder:scaffold:webhook

go func() {
Expand Down
31 changes: 22 additions & 9 deletions apis/clusters/v1beta1/cassandra_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,15 @@ type Spark struct {
Version string `json:"version"`
}

type CassandraRestoreDC struct {
CDCID string `json:"cdcId,omitempty"`
RestoreToSameVPC bool `json:"restoreToSameVpc,omitempty"`
CustomVPCID string `json:"customVpcId,omitempty"`
CustomVPCNetwork string `json:"customVpcNetwork,omitempty"`
}

type CassandraRestoreFrom struct {
// Original cluster ID. Backup from that cluster will be used for restore
ClusterID string `json:"clusterID"`

// The display name of the restored cluster.
ClusterNameOverride string `json:"clusterNameOverride,omitempty"`
RestoredClusterName string `json:"restoredClusterName,omitempty"`

// An optional list of cluster data centres for which custom VPC settings will be used.
CDCInfos []CassandraRestoreDC `json:"cdcInfos,omitempty"`
CDCConfigs []*RestoreCDCConfig `json:"cdcConfigs,omitempty"`

// Timestamp in milliseconds since epoch. All backed up data will be restored for this point in time.
PointInTime int64 `json:"pointInTime,omitempty"`
Expand Down Expand Up @@ -366,6 +359,26 @@ func (cs *CassandraSpec) ToInstAPI() *models.CassandraCluster {
}
}

func (c *Cassandra) RestoreInfoToInstAPI(restoreData *CassandraRestoreFrom) any {
iRestore := struct {
RestoredClusterName string `json:"restoredClusterName,omitempty"`
CDCConfigs []*RestoreCDCConfig `json:"cdcConfigs,omitempty"`
PointInTime int64 `json:"pointInTime,omitempty"`
KeyspaceTables string `json:"keyspaceTables,omitempty"`
ClusterNetwork string `json:"clusterNetwork,omitempty"`
ClusterID string `json:"clusterId,omitempty"`
}{
CDCConfigs: restoreData.CDCConfigs,
RestoredClusterName: restoreData.RestoredClusterName,
PointInTime: restoreData.PointInTime,
KeyspaceTables: restoreData.KeyspaceTables,
ClusterNetwork: restoreData.ClusterNetwork,
ClusterID: restoreData.ClusterID,
}

return iRestore
}

func (cs *CassandraSpec) SparkToInstAPI() (iSparks []*models.Spark) {
for _, spark := range cs.Spark {
iSparks = append(iSparks, &models.Spark{
Expand Down
32 changes: 20 additions & 12 deletions apis/clusters/v1beta1/opensearch_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,24 @@ func (oss *OpenSearchSpec) FromInstAPI(iOpenSearch *models.OpenSearchCluster) Op
}
}

func (oss *OpenSearch) RestoreInfoToInstAPI(restoreData *OpenSearchRestoreFrom) any {
iRestore := struct {
RestoredClusterName string `json:"restoredClusterName,omitempty"`
CDCConfigs []*RestoreCDCConfig `json:"cdcConfigs,omitempty"`
PointInTime int64 `json:"pointInTime,omitempty"`
IndexNames string `json:"indexNames,omitempty"`
ClusterID string `json:"clusterId,omitempty"`
}{
RestoredClusterName: restoreData.RestoredClusterName,
CDCConfigs: restoreData.CDCConfigs,
PointInTime: restoreData.PointInTime,
IndexNames: restoreData.IndexNames,
ClusterID: restoreData.ClusterID,
}

return iRestore
}

func (oss *OpenSearchSpec) DCsFromInstAPI(iDCs []*models.OpenSearchDataCentre) (dcs []*OpenSearchDataCentre) {
for _, iDC := range iDCs {
dcs = append(dcs, &OpenSearchDataCentre{
Expand Down Expand Up @@ -465,26 +483,16 @@ type OpenSearchRestoreFrom struct {
ClusterID string `json:"clusterId"`

// The display name of the restored cluster.
ClusterNameOverride string `json:"clusterNameOverride,omitempty"`
RestoredClusterName string `json:"restoredClusterName,omitempty"`

// An optional list of cluster data centres for which custom VPC settings will be used.
CDCInfos []*OpenSearchRestoreCDCInfo `json:"cdcInfos,omitempty"`
CDCConfigs []*RestoreCDCConfig `json:"cdcConfigs,omitempty"`

// Timestamp in milliseconds since epoch. All backed up data will be restored for this point in time.
PointInTime int64 `json:"pointInTime,omitempty"`

// Only data for the specified indices will be restored, for the point in time.
IndexNames string `json:"indexNames,omitempty"`

// The cluster network for this cluster to be restored to.
ClusterNetwork string `json:"clusterNetwork,omitempty"`
}

type OpenSearchRestoreCDCInfo struct {
CDCID string `json:"cdcId,omitempty"`
RestoreToSameVPC bool `json:"restoreToSameVpc,omitempty"`
CustomVPCID string `json:"customVpcId,omitempty"`
CustomVPCNetwork string `json:"customVpcNetwork,omitempty"`
}

// OpenSearchStatus defines the observed state of OpenSearch
Expand Down
30 changes: 18 additions & 12 deletions apis/clusters/v1beta1/postgresql_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,23 +62,13 @@ type PgRestoreFrom struct {
ClusterID string `json:"clusterId"`

// The display name of the restored cluster.
ClusterNameOverride string `json:"clusterNameOverride,omitempty"`
RestoredClusterName string `json:"restoredClusterName,omitempty"`

// An optional list of cluster data centres for which custom VPC settings will be used.
CDCInfos []*PgRestoreCDCInfo `json:"cdcInfos,omitempty"`
CDCConfigs []*RestoreCDCConfig `json:"cdsConfigs,omitempty"`

// Timestamp in milliseconds since epoch. All backed up data will be restored for this point in time.
PointInTime int64 `json:"pointInTime,omitempty"`

// The cluster network for this cluster to be restored to.
ClusterNetwork string `json:"clusterNetwork,omitempty"`
}

type PgRestoreCDCInfo struct {
CDCID string `json:"cdcId,omitempty"`
RestoreToSameVPC bool `json:"restoreToSameVpc,omitempty"`
CustomVPCID string `json:"customVpcId,omitempty"`
CustomVPCNetwork string `json:"customVpcNetwork,omitempty"`
}

// PgSpec defines the desired state of PostgreSQL
Expand Down Expand Up @@ -176,6 +166,22 @@ func (pg *PostgreSQL) NewBackupSpec(startTimestamp int) *clusterresourcesv1beta1
}
}

func (pg *PostgreSQL) RestoreInfoToInstAPI(restoreData *PgRestoreFrom) any {
iRestore := struct {
CDCConfigs []*RestoreCDCConfig `json:"cdcConfigs,omitempty"`
PointInTime int64 `json:"pointInTime,omitempty"`
ClusterID string `json:"clusterId,omitempty"`
RestoredClusterName string `json:"restoredClusterName,omitempty"`
}{
CDCConfigs: restoreData.CDCConfigs,
PointInTime: restoreData.PointInTime,
ClusterID: restoreData.ClusterID,
RestoredClusterName: restoreData.RestoredClusterName,
}

return iRestore
}

func (pgs *PgSpec) HasRestore() bool {
if pgs.PgRestoreFrom != nil && pgs.PgRestoreFrom.ClusterID != "" {
return true
Expand Down
31 changes: 19 additions & 12 deletions apis/clusters/v1beta1/redis_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,26 +46,16 @@ type RedisRestoreFrom struct {
ClusterID string `json:"clusterId"`

// The display name of the restored cluster.
ClusterNameOverride string `json:"clusterNameOverride,omitempty"`
RestoredClusterName string `json:"restoredClusterName,omitempty"`

// An optional list of cluster data centres for which custom VPC settings will be used.
CDCInfos []*RedisRestoreCDCInfo `json:"cdcInfos,omitempty"`
CDCConfigs []*RestoreCDCConfig `json:"cdcConfigs,omitempty"`

// Timestamp in milliseconds since epoch. All backed up data will be restored for this point in time.
PointInTime int64 `json:"pointInTime,omitempty"`

// Only data for the specified indices will be restored, for the point in time.
IndexNames string `json:"indexNames,omitempty"`

// The cluster network for this cluster to be restored to.
ClusterNetwork string `json:"clusterNetwork,omitempty"`
}

type RedisRestoreCDCInfo struct {
CDCID string `json:"cdcId,omitempty"`
RestoreToSameVPC bool `json:"restoreToSameVpc,omitempty"`
CustomVPCID string `json:"customVpcId,omitempty"`
CustomVPCNetwork string `json:"customVpcNetwork,omitempty"`
}

// RedisSpec defines the desired state of Redis
Expand Down Expand Up @@ -172,6 +162,23 @@ func (rs *RedisSpec) ToInstAPI() *models.RedisCluster {
}
}

func (r *Redis) RestoreInfoToInstAPI(restoreData *RedisRestoreFrom) any {
iRestore := struct {
CDCConfigs []*RestoreCDCConfig `json:"cdcConfigs,omitempty"`
PointInTime int64 `json:"pointInTime,omitempty"`
ClusterID string `json:"clusterId,omitempty"`
RestoredClusterName string `json:"restoredClusterName,omitempty"`
}{

CDCConfigs: restoreData.CDCConfigs,
PointInTime: restoreData.PointInTime,
ClusterID: restoreData.ClusterID,
RestoredClusterName: restoreData.RestoredClusterName,
}

return iRestore
}

func (rs *RedisSpec) DCsToInstAPI() (iDCs []*models.RedisDataCentre) {
for _, redisDC := range rs.DataCentres {
iSettings := redisDC.CloudProviderSettingsToInstAPI()
Expand Down
11 changes: 11 additions & 0 deletions apis/clusters/v1beta1/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ type DataCentreStatus struct {
ResizeOperations []*ResizeOperation `json:"resizeOperations,omitempty"`
}

type RestoreCDCConfig struct {
CustomVPCSettings *RestoreCustomVPCSettings `json:"customVpcSettings,omitempty"`
RestoreMode string `json:"restoreMode,omitempty"`
CDCID string `json:"cdcId,omitempty"`
}

type RestoreCustomVPCSettings struct {
VpcID string `json:"vpcId,omitempty"`
Network string `json:"network,omitempty"`
}

type Node struct {
ID string `json:"id,omitempty"`
Size string `json:"size,omitempty"`
Expand Down
Loading

0 comments on commit a56f873

Please sign in to comment.