Skip to content
This repository has been archived by the owner on Mar 4, 2024. It is now read-only.

Commit

Permalink
EVEREST-495 Add multi namespaces (#428)
Browse files Browse the repository at this point in the history
  • Loading branch information
recharte authored Feb 7, 2024
1 parent e234517 commit d0eaa02
Show file tree
Hide file tree
Showing 37 changed files with 2,382 additions and 2,053 deletions.
86 changes: 56 additions & 30 deletions api/backup_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ func (e *EverestServer) ListBackupStorages(ctx echo.Context) error {
for _, bs := range backupList.Items {
s := bs
result = append(result, BackupStorage{
Type: BackupStorageType(bs.Spec.Type),
Name: s.Name,
Description: &s.Spec.Description,
BucketName: s.Spec.Bucket,
Region: s.Spec.Region,
Url: &s.Spec.EndpointURL,
Type: BackupStorageType(bs.Spec.Type),
Name: s.Name,
Description: &s.Spec.Description,
BucketName: s.Spec.Bucket,
Region: s.Spec.Region,
Url: &s.Spec.EndpointURL,
TargetNamespaces: s.Spec.TargetNamespaces,
})
}

Expand All @@ -55,7 +56,15 @@ func (e *EverestServer) ListBackupStorages(ctx echo.Context) error {

// CreateBackupStorage creates a new backup storage object.
func (e *EverestServer) CreateBackupStorage(ctx echo.Context) error { //nolint:funlen
params, err := validateCreateBackupStorageRequest(ctx, e.l)
namespaces, err := e.kubeClient.GetDBNamespaces(ctx.Request().Context(), e.kubeClient.Namespace())
if err != nil {
e.l.Error(err)
return ctx.JSON(http.StatusInternalServerError, Error{
Message: pointer.ToString("Failed getting watched namespaces"),
})
}

params, err := validateCreateBackupStorageRequest(ctx, namespaces, e.l)
if err != nil {
return ctx.JSON(http.StatusBadRequest, Error{Message: pointer.ToString(err.Error())})
}
Expand Down Expand Up @@ -111,6 +120,7 @@ func (e *EverestServer) CreateBackupStorage(ctx echo.Context) error { //nolint:f
Bucket: params.BucketName,
Region: params.Region,
CredentialsSecretName: params.Name,
TargetNamespaces: params.TargetNamespaces,
},
}
if params.Url != nil {
Expand All @@ -123,7 +133,7 @@ func (e *EverestServer) CreateBackupStorage(ctx echo.Context) error { //nolint:f
if err != nil {
e.l.Error(err)
// TODO: Move this logic to the operator
dErr := e.kubeClient.DeleteSecret(c, params.Name)
dErr := e.kubeClient.DeleteSecret(c, e.kubeClient.Namespace(), params.Name)
if dErr != nil {
return ctx.JSON(http.StatusInternalServerError, Error{
Message: pointer.ToString("Failed cleaning up secret for a backup storage"),
Expand All @@ -134,12 +144,13 @@ func (e *EverestServer) CreateBackupStorage(ctx echo.Context) error { //nolint:f
})
}
result := BackupStorage{
Type: BackupStorageType(params.Type),
Name: params.Name,
Description: params.Description,
BucketName: params.BucketName,
Region: params.Region,
Url: params.Url,
Type: BackupStorageType(params.Type),
Name: params.Name,
Description: params.Description,
BucketName: params.BucketName,
Region: params.Region,
Url: params.Url,
TargetNamespaces: params.TargetNamespaces,
}

return ctx.JSON(http.StatusOK, result)
Expand Down Expand Up @@ -173,7 +184,7 @@ func (e *EverestServer) DeleteBackupStorage(ctx echo.Context, backupStorageName
Message: pointer.ToString("Failed to delete a backup storage"),
})
}
if err := e.kubeClient.DeleteSecret(ctx.Request().Context(), backupStorageName); err != nil {
if err := e.kubeClient.DeleteSecret(ctx.Request().Context(), e.kubeClient.Namespace(), backupStorageName); err != nil {
if k8serrors.IsNotFound(err) {
return ctx.NoContent(http.StatusNoContent)
}
Expand Down Expand Up @@ -208,17 +219,18 @@ func (e *EverestServer) GetBackupStorage(ctx echo.Context, backupStorageName str
})
}
return ctx.JSON(http.StatusOK, BackupStorage{
Type: BackupStorageType(s.Spec.Type),
Name: s.Name,
Description: &s.Spec.Description,
BucketName: s.Spec.Bucket,
Region: s.Spec.Region,
Url: &s.Spec.EndpointURL,
Type: BackupStorageType(s.Spec.Type),
Name: s.Name,
Description: &s.Spec.Description,
BucketName: s.Spec.Bucket,
Region: s.Spec.Region,
Url: &s.Spec.EndpointURL,
TargetNamespaces: s.Spec.TargetNamespaces,
})
}

// UpdateBackupStorage updates of the specified backup storage.
func (e *EverestServer) UpdateBackupStorage(ctx echo.Context, backupStorageName string) error { //nolint:funlen
func (e *EverestServer) UpdateBackupStorage(ctx echo.Context, backupStorageName string) error { //nolint:funlen,cyclop
c := ctx.Request().Context()
bs, err := e.kubeClient.GetBackupStorage(c, backupStorageName)
if err != nil {
Expand All @@ -232,7 +244,8 @@ func (e *EverestServer) UpdateBackupStorage(ctx echo.Context, backupStorageName
Message: pointer.ToString("Failed getting backup storage"),
})
}
secret, err := e.kubeClient.GetSecret(c, backupStorageName)

secret, err := e.kubeClient.GetSecret(c, e.kubeClient.Namespace(), backupStorageName)
if err != nil {
if k8serrors.IsNotFound(err) {
return ctx.JSON(http.StatusNotFound, Error{
Expand All @@ -244,7 +257,16 @@ func (e *EverestServer) UpdateBackupStorage(ctx echo.Context, backupStorageName
Message: pointer.ToString("Failed getting secret"),
})
}
params, err := validateUpdateBackupStorageRequest(ctx, bs, secret, e.l)

namespaces, err := e.kubeClient.GetDBNamespaces(ctx.Request().Context(), e.kubeClient.Namespace())
if err != nil {
e.l.Error(err)
return ctx.JSON(http.StatusInternalServerError, Error{
Message: pointer.ToString("Failed getting watched namespaces"),
})
}

params, err := validateUpdateBackupStorageRequest(ctx, bs, secret, namespaces, e.l)
if err != nil {
return ctx.JSON(http.StatusBadRequest, Error{Message: pointer.ToString(err.Error())})
}
Expand Down Expand Up @@ -276,6 +298,9 @@ func (e *EverestServer) UpdateBackupStorage(ctx echo.Context, backupStorageName
if params.Description != nil {
bs.Spec.Description = *params.Description
}
if params.TargetNamespaces != nil {
bs.Spec.TargetNamespaces = *params.TargetNamespaces
}

err = e.kubeClient.UpdateBackupStorage(c, bs)
if err != nil {
Expand All @@ -285,12 +310,13 @@ func (e *EverestServer) UpdateBackupStorage(ctx echo.Context, backupStorageName
})
}
result := BackupStorage{
Type: BackupStorageType(bs.Spec.Type),
Name: bs.Name,
Description: params.Description,
BucketName: bs.Spec.Bucket,
Region: bs.Spec.Region,
Url: &bs.Spec.EndpointURL,
Type: BackupStorageType(bs.Spec.Type),
Name: bs.Name,
Description: params.Description,
BucketName: bs.Spec.Bucket,
Region: bs.Spec.Region,
Url: &bs.Spec.EndpointURL,
TargetNamespaces: bs.Spec.TargetNamespaces,
}

return ctx.JSON(http.StatusOK, result)
Expand Down
42 changes: 23 additions & 19 deletions api/database_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
databaseClusterKind = "databaseclusters"
)

// CreateDatabaseCluster creates a new db cluster inside the given k8s cluster.
func (e *EverestServer) CreateDatabaseCluster(ctx echo.Context) error {
func (e *EverestServer) CreateDatabaseCluster(ctx echo.Context, namespace string) error {
dbc := &DatabaseCluster{}
if err := e.getBodyFromContext(ctx, dbc); err != nil {
e.l.Error(err)
Expand All @@ -38,30 +42,30 @@ func (e *EverestServer) CreateDatabaseCluster(ctx echo.Context) error {
})
}

if err := e.validateDatabaseClusterCR(ctx, dbc); err != nil {
if err := e.validateDatabaseClusterCR(ctx, namespace, dbc); err != nil {
return ctx.JSON(http.StatusBadRequest, Error{Message: pointer.ToString(err.Error())})
}

return e.proxyKubernetes(ctx, "")
return e.proxyKubernetes(ctx, namespace, databaseClusterKind, "")
}

// ListDatabaseClusters lists the created database clusters on the specified kubernetes cluster.
func (e *EverestServer) ListDatabaseClusters(ctx echo.Context) error {
return e.proxyKubernetes(ctx, "")
func (e *EverestServer) ListDatabaseClusters(ctx echo.Context, namespace string) error {
return e.proxyKubernetes(ctx, namespace, databaseClusterKind, "")
}

// DeleteDatabaseCluster deletes a database cluster on the specified kubernetes cluster.
func (e *EverestServer) DeleteDatabaseCluster(ctx echo.Context, name string) error {
return e.proxyKubernetes(ctx, name)
func (e *EverestServer) DeleteDatabaseCluster(ctx echo.Context, namespace, name string) error {
return e.proxyKubernetes(ctx, namespace, databaseClusterKind, name)
}

// GetDatabaseCluster retrieves the specified database cluster on the specified kubernetes cluster.
func (e *EverestServer) GetDatabaseCluster(ctx echo.Context, name string) error {
return e.proxyKubernetes(ctx, name)
func (e *EverestServer) GetDatabaseCluster(ctx echo.Context, namespace, name string) error {
return e.proxyKubernetes(ctx, namespace, databaseClusterKind, name)
}

// UpdateDatabaseCluster replaces the specified database cluster on the specified kubernetes cluster.
func (e *EverestServer) UpdateDatabaseCluster(ctx echo.Context, name string) error {
func (e *EverestServer) UpdateDatabaseCluster(ctx echo.Context, namespace, name string) error {
dbc := &DatabaseCluster{}
if err := e.getBodyFromContext(ctx, dbc); err != nil {
e.l.Error(err)
Expand All @@ -70,29 +74,29 @@ func (e *EverestServer) UpdateDatabaseCluster(ctx echo.Context, name string) err
})
}

if err := e.validateDatabaseClusterCR(ctx, dbc); err != nil {
if err := e.validateDatabaseClusterCR(ctx, namespace, dbc); err != nil {
return ctx.JSON(http.StatusBadRequest, Error{Message: pointer.ToString(err.Error())})
}

oldDB, err := e.kubeClient.GetDatabaseCluster(ctx.Request().Context(), name)
oldDB, err := e.kubeClient.GetDatabaseCluster(ctx.Request().Context(), namespace, name)
if err != nil {
return errors.Join(err, errors.New("could not get old Database Cluster"))
}
if err := validateDatabaseClusterOnUpdate(dbc, oldDB); err != nil {
return ctx.JSON(http.StatusBadRequest, Error{Message: pointer.ToString(err.Error())})
}

return e.proxyKubernetes(ctx, name)
return e.proxyKubernetes(ctx, namespace, databaseClusterKind, name)
}

// GetDatabaseClusterCredentials returns credentials for the specified database cluster.
func (e *EverestServer) GetDatabaseClusterCredentials(ctx echo.Context, name string) error {
databaseCluster, err := e.kubeClient.GetDatabaseCluster(ctx.Request().Context(), name)
func (e *EverestServer) GetDatabaseClusterCredentials(ctx echo.Context, namespace, name string) error {
databaseCluster, err := e.kubeClient.GetDatabaseCluster(ctx.Request().Context(), namespace, name)
if err != nil {
e.l.Error(err)
return ctx.JSON(http.StatusInternalServerError, Error{Message: pointer.ToString(err.Error())})
}
secret, err := e.kubeClient.GetSecret(ctx.Request().Context(), databaseCluster.Spec.Engine.UserSecretsName)
secret, err := e.kubeClient.GetSecret(ctx.Request().Context(), namespace, databaseCluster.Spec.Engine.UserSecretsName)
if err != nil {
e.l.Error(err)
return ctx.JSON(http.StatusInternalServerError, Error{Message: pointer.ToString(err.Error())})
Expand All @@ -116,8 +120,8 @@ func (e *EverestServer) GetDatabaseClusterCredentials(ctx echo.Context, name str
}

// GetDatabaseClusterPitr returns the point-in-time recovery related information for the specified database cluster.
func (e *EverestServer) GetDatabaseClusterPitr(ctx echo.Context, name string) error {
databaseCluster, err := e.kubeClient.GetDatabaseCluster(ctx.Request().Context(), name)
func (e *EverestServer) GetDatabaseClusterPitr(ctx echo.Context, namespace, name string) error {
databaseCluster, err := e.kubeClient.GetDatabaseCluster(ctx.Request().Context(), namespace, name)
if err != nil {
e.l.Error(err)
return ctx.JSON(http.StatusInternalServerError, Error{Message: pointer.ToString(err.Error())})
Expand All @@ -135,7 +139,7 @@ func (e *EverestServer) GetDatabaseClusterPitr(ctx echo.Context, name string) er
},
}),
}
backups, err := e.kubeClient.ListDatabaseClusterBackups(ctx.Request().Context(), options)
backups, err := e.kubeClient.ListDatabaseClusterBackups(ctx.Request().Context(), namespace, options)
if err != nil {
e.l.Error(err)
return ctx.JSON(http.StatusInternalServerError, Error{Message: pointer.ToString(err.Error())})
Expand Down
22 changes: 13 additions & 9 deletions api/database_cluster_backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ import (
"github.com/labstack/echo/v4"
)

const (
databaseClusterBackupKind = "databaseclusterbackups"
)

// ListDatabaseClusterBackups returns list of the created database cluster backups on the specified kubernetes cluster.
func (e *EverestServer) ListDatabaseClusterBackups(ctx echo.Context, name string) error {
func (e *EverestServer) ListDatabaseClusterBackups(ctx echo.Context, namespace, name string) error {
req := ctx.Request()
if err := validateRFC1035(name, "name"); err != nil {
return ctx.JSON(http.StatusBadRequest, Error{Message: pointer.ToString(err.Error())})
Expand All @@ -42,11 +46,11 @@ func (e *EverestServer) ListDatabaseClusterBackups(ctx echo.Context, name string
path = strings.TrimSuffix(path, name)
path = strings.ReplaceAll(path, "database-clusters", "database-cluster-backups")
req.URL.Path = path
return e.proxyKubernetes(ctx, "")
return e.proxyKubernetes(ctx, namespace, databaseClusterBackupKind, "")
}

// CreateDatabaseClusterBackup creates a database cluster backup on the specified kubernetes cluster.
func (e *EverestServer) CreateDatabaseClusterBackup(ctx echo.Context) error {
func (e *EverestServer) CreateDatabaseClusterBackup(ctx echo.Context, namespace string) error {
dbb := &DatabaseClusterBackup{}
if err := e.getBodyFromContext(ctx, dbb); err != nil {
e.l.Error(err)
Expand All @@ -55,19 +59,19 @@ func (e *EverestServer) CreateDatabaseClusterBackup(ctx echo.Context) error {
})
}
// TODO: Improve returns status code in EVEREST-616
if err := validateDatabaseClusterBackup(ctx.Request().Context(), dbb, e.kubeClient); err != nil {
if err := validateDatabaseClusterBackup(ctx.Request().Context(), namespace, dbb, e.kubeClient); err != nil {
e.l.Error(err)
return ctx.JSON(http.StatusBadRequest, Error{Message: pointer.ToString(err.Error())})
}
return e.proxyKubernetes(ctx, "")
return e.proxyKubernetes(ctx, namespace, databaseClusterBackupKind, "")
}

// DeleteDatabaseClusterBackup deletes the specified cluster backup on the specified kubernetes cluster.
func (e *EverestServer) DeleteDatabaseClusterBackup(ctx echo.Context, name string) error {
return e.proxyKubernetes(ctx, name)
func (e *EverestServer) DeleteDatabaseClusterBackup(ctx echo.Context, namespace, name string) error {
return e.proxyKubernetes(ctx, namespace, databaseClusterBackupKind, name)
}

// GetDatabaseClusterBackup returns the specified cluster backup on the specified kubernetes cluster.
func (e *EverestServer) GetDatabaseClusterBackup(ctx echo.Context, name string) error {
return e.proxyKubernetes(ctx, name)
func (e *EverestServer) GetDatabaseClusterBackup(ctx echo.Context, namespace, name string) error {
return e.proxyKubernetes(ctx, namespace, databaseClusterBackupKind, name)
}
Loading

0 comments on commit d0eaa02

Please sign in to comment.