250 lines
8.0 KiB
Go
250 lines
8.0 KiB
Go
package factory
|
|
|
|
import (
|
|
"errors"
|
|
polardbxv1 "github.com/alibaba/polardbx-operator/api/v1"
|
|
polardbxv1polardbx "github.com/alibaba/polardbx-operator/api/v1/polardbx"
|
|
"github.com/alibaba/polardbx-operator/pkg/operator/v1/polardbx/convention"
|
|
"github.com/alibaba/polardbx-operator/pkg/operator/v1/polardbx/meta"
|
|
"github.com/alibaba/polardbx-operator/pkg/util/name"
|
|
corev1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
)
|
|
|
|
type PolarDBXClusterMetadata struct {
|
|
// Name records name of original pxc
|
|
Name string `json:"name,omitempty"`
|
|
|
|
// UID records uid of original pxc
|
|
UID types.UID `json:"uid,omitempty"`
|
|
|
|
// Spec records the topology from original pxc
|
|
Spec *polardbxv1.PolarDBXClusterSpec `json:"spec,omitempty"`
|
|
|
|
// Secrets records account and password for pxc
|
|
Secrets []polardbxv1polardbx.PrivilegeItem `json:"secrets,omitempty"`
|
|
}
|
|
|
|
type XstoreMetadata struct {
|
|
// Name records name of original xstore
|
|
Name string `json:"name,omitempty"`
|
|
|
|
// UID records uid of original xstore
|
|
UID types.UID `json:"uid,omitempty"`
|
|
|
|
// BackupName records name of xstore backup of original xstore
|
|
BackupName string `json:"backupName,omitempty"`
|
|
|
|
// LastCommitIndex records the last binlog index during full backup
|
|
LastCommitIndex int64 `json:"lastCommitIndex,omitempty"`
|
|
|
|
// Secrets records account and password for xstore
|
|
Secrets []polardbxv1polardbx.PrivilegeItem `json:"secrets,omitempty"`
|
|
}
|
|
|
|
// MetadataBackup defines metadata to be uploaded during backup
|
|
type MetadataBackup struct {
|
|
|
|
// PolarDBXClusterMetadata records metadata of pxc which backed up
|
|
PolarDBXClusterMetadata PolarDBXClusterMetadata `json:"polarDBXClusterMetadata,omitempty"`
|
|
|
|
// XstoreMetadataList records metadata of each xstore which backed up
|
|
XstoreMetadataList []XstoreMetadata `json:"xstoreMetadataList,omitempty"`
|
|
|
|
// BackupSetName records name of pxb
|
|
BackupSetName string `json:"backupSetName,omitempty"`
|
|
|
|
// BackupRootPath records the root path for pxb
|
|
BackupRootPath string `json:"backupRootPath,omitempty"`
|
|
|
|
// StartTime records start time of backup
|
|
StartTime *metav1.Time `json:"startTime,omitempty"`
|
|
|
|
// EndTime records end time of backup
|
|
EndTime *metav1.Time `json:"endTime,omitempty"`
|
|
|
|
// LatestRecoverableTimestamp records the latest timestamp that can recover from current backup set
|
|
LatestRecoverableTimestamp *metav1.Time `json:"latestRecoverableTimestamp,omitempty"`
|
|
}
|
|
|
|
func (m *MetadataBackup) GetXstoreNameList() []string {
|
|
xstoreNameList := make([]string, len(m.XstoreMetadataList))
|
|
for i, xstoreMetadata := range m.XstoreMetadataList {
|
|
xstoreNameList[i] = xstoreMetadata.Name
|
|
}
|
|
return xstoreNameList
|
|
}
|
|
|
|
func (m *MetadataBackup) GetXstoreMetadataByName(xstoreName string) (*XstoreMetadata, error) {
|
|
for i := range m.XstoreMetadataList {
|
|
if m.XstoreMetadataList[i].Name == xstoreName {
|
|
return &m.XstoreMetadataList[i], nil
|
|
}
|
|
}
|
|
return nil, errors.New("no such metadata related to xstore " + xstoreName)
|
|
}
|
|
|
|
func (f *objectFactory) NewPolarDBXBackupBySchedule() (*polardbxv1.PolarDBXBackup, error) {
|
|
backupSchedule := f.rc.MustGetPolarDBXBackupSchedule()
|
|
backupName := name.NewSplicedName(
|
|
name.WithTokens(backupSchedule.Spec.BackupSpec.Cluster.Name, "backup",
|
|
backupSchedule.Status.NextBackupTime.Format("200601021504")),
|
|
name.WithPrefix("scheduled-backup"),
|
|
)
|
|
backup := &polardbxv1.PolarDBXBackup{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Namespace: backupSchedule.Namespace,
|
|
Name: backupName,
|
|
Labels: map[string]string{
|
|
meta.LabelBackupSchedule: backupSchedule.Name,
|
|
},
|
|
},
|
|
Spec: *backupSchedule.Spec.BackupSpec.DeepCopy(),
|
|
}
|
|
return backup, nil
|
|
}
|
|
|
|
func (f *objectFactory) NewXStoreBackup(
|
|
xstore *polardbxv1.XStore) (*polardbxv1.XStoreBackup, error) {
|
|
backup := f.rc.MustGetPolarDBXBackup()
|
|
xstoreBackup := &polardbxv1.XStoreBackup{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Namespace: backup.Namespace,
|
|
Name: name.NewSplicedName(
|
|
name.WithTokens(backup.Name, xstore.Name),
|
|
name.WithPrefix("xstore-backup"),
|
|
),
|
|
Labels: map[string]string{
|
|
meta.LabelName: backup.Spec.Cluster.Name,
|
|
meta.LabelTopBackup: backup.Name,
|
|
meta.LabelBackupXStore: xstore.Name,
|
|
meta.LabelBackupXStoreUID: string(xstore.UID),
|
|
},
|
|
},
|
|
Spec: polardbxv1.XStoreBackupSpec{
|
|
XStore: polardbxv1.XStoreReference{
|
|
Name: xstore.Name,
|
|
UID: xstore.UID,
|
|
},
|
|
RetentionTime: backup.Spec.RetentionTime,
|
|
StorageProvider: backup.Spec.StorageProvider,
|
|
Engine: xstore.Spec.Engine,
|
|
PreferredBackupRole: backup.Spec.PreferredBackupRole,
|
|
},
|
|
}
|
|
|
|
return xstoreBackup, nil
|
|
}
|
|
|
|
func (f *objectFactory) newDummyAnnotation() map[string]string {
|
|
return map[string]string{
|
|
meta.AnnotationDummyBackup: "true",
|
|
}
|
|
}
|
|
|
|
func (f *objectFactory) NewDummyPolarDBXBackup(metadata *MetadataBackup) (*polardbxv1.PolarDBXBackup, error) {
|
|
if metadata == nil {
|
|
return nil, errors.New("not enough information to create dummy polardbx backup")
|
|
}
|
|
polardbx := f.rc.MustGetPolarDBX()
|
|
polardbxBackup := &polardbxv1.PolarDBXBackup{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name.NewSplicedName(
|
|
name.WithTokens(metadata.BackupSetName, "dummy"),
|
|
name.WithPrefix("dummy-backup"),
|
|
),
|
|
Namespace: polardbx.Namespace,
|
|
Annotations: f.newDummyAnnotation(),
|
|
},
|
|
Spec: polardbxv1.PolarDBXBackupSpec{
|
|
Cluster: polardbxv1.PolarDBXClusterReference{
|
|
Name: metadata.PolarDBXClusterMetadata.Name,
|
|
UID: metadata.PolarDBXClusterMetadata.UID,
|
|
},
|
|
StorageProvider: *polardbx.Spec.Restore.StorageProvider,
|
|
},
|
|
Status: polardbxv1.PolarDBXBackupStatus{
|
|
Phase: polardbxv1.BackupDummy,
|
|
BackupRootPath: polardbx.Spec.Restore.From.BackupSetPath,
|
|
ClusterSpecSnapshot: metadata.PolarDBXClusterMetadata.Spec,
|
|
XStores: metadata.GetXstoreNameList(),
|
|
Backups: make(map[string]string),
|
|
},
|
|
}
|
|
return polardbxBackup, nil
|
|
}
|
|
|
|
func (f *objectFactory) NewDummyXstoreBackup(xstoreName string, polardbxBackup *polardbxv1.PolarDBXBackup,
|
|
metadata *MetadataBackup) (*polardbxv1.XStoreBackup, error) {
|
|
if metadata == nil {
|
|
return nil, errors.New("not enough information to create dummy xstore backup")
|
|
}
|
|
xstoreMetadata, err := metadata.GetXstoreMetadataByName(xstoreName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
xstoreBackup := &polardbxv1.XStoreBackup{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name.NewSplicedName(
|
|
name.WithTokens(polardbxBackup.Name, xstoreName),
|
|
name.WithPrefix("dummy-xstore-backup"),
|
|
),
|
|
Namespace: polardbxBackup.Namespace,
|
|
Annotations: f.newDummyAnnotation(),
|
|
},
|
|
Spec: polardbxv1.XStoreBackupSpec{
|
|
XStore: polardbxv1.XStoreReference{
|
|
Name: xstoreName,
|
|
UID: xstoreMetadata.UID,
|
|
},
|
|
StorageProvider: polardbxBackup.Spec.StorageProvider,
|
|
},
|
|
Status: polardbxv1.XStoreBackupStatus{
|
|
Phase: polardbxv1.XStoreBackupDummy,
|
|
CommitIndex: xstoreMetadata.LastCommitIndex,
|
|
BackupRootPath: metadata.BackupRootPath,
|
|
},
|
|
}
|
|
return xstoreBackup, nil
|
|
}
|
|
|
|
func (f *objectFactory) NewDummySecretBackup(sourceSecretName string, metadata *MetadataBackup) (*corev1.Secret, error) {
|
|
polardbx := f.rc.MustGetPolarDBX()
|
|
|
|
var dummySecretName string
|
|
var sourceSecrets *[]polardbxv1polardbx.PrivilegeItem
|
|
accounts := make(map[string]string)
|
|
|
|
if sourceSecretName == metadata.PolarDBXClusterMetadata.Name {
|
|
// secret of cn
|
|
dummySecretName = name.NewSplicedName(
|
|
name.WithTokens(metadata.BackupSetName, "dummy"),
|
|
name.WithPrefix("dummy-secret"),
|
|
)
|
|
sourceSecrets = &metadata.PolarDBXClusterMetadata.Secrets
|
|
} else {
|
|
// secret of dn
|
|
dummySecretName = name.NewSplicedName(
|
|
name.WithTokens(metadata.BackupSetName, "dummy", sourceSecretName),
|
|
name.WithPrefix("dummy-xstore-secret"),
|
|
)
|
|
xstoreMetadata, err := metadata.GetXstoreMetadataByName(sourceSecretName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
sourceSecrets = &xstoreMetadata.Secrets
|
|
}
|
|
for _, item := range *sourceSecrets {
|
|
accounts[item.Username] = item.Password
|
|
}
|
|
return &corev1.Secret{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: dummySecretName,
|
|
Namespace: polardbx.Namespace,
|
|
Labels: convention.ConstLabels(polardbx),
|
|
},
|
|
StringData: accounts,
|
|
}, nil
|
|
}
|