mirror of
https://github.com/arangodb/kube-arangodb.git
synced 2024-12-14 11:57:37 +00:00
GT-350 Backup lifetime - remove Backup once its lifetime has been reached (#1262)
This commit is contained in:
parent
87f558fae4
commit
34ae2c0f82
11 changed files with 139 additions and 9 deletions
|
@ -1,6 +1,7 @@
|
|||
# Change Log
|
||||
|
||||
## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A)
|
||||
- (Feature) Backup lifetime - remove Backup once its lifetime has been reached
|
||||
|
||||
## [1.2.31](https://github.com/arangodb/kube-arangodb/tree/1.2.31) (2023-07-14)
|
||||
- (Improvement) Block traffic on the services if there is more than 1 active leader in ActiveFailover mode
|
||||
|
|
|
@ -18,8 +18,9 @@
|
|||
- [Operator API](./api.md)
|
||||
- [Logging](./logging.md)
|
||||
- [Manual Recovery](./recovery.md)
|
||||
- [Backup](./backup.md)
|
||||
|
||||
## Features
|
||||
- [Force rebuild out-synced Shards with broken Merkle Tree](./features/rebuild_out_synced_shards.md)
|
||||
- [Failover Leader service](./features/failover_leader_service.md)
|
||||
- [Restore defaults from last accepted state of deployment](./features/deployment_spec_defaults.md)
|
||||
- [Restore defaults from last accepted state of deployment](./features/deployment_spec_defaults.md)
|
||||
|
|
59
docs/design/backup.md
Normal file
59
docs/design/backup.md
Normal file
|
@ -0,0 +1,59 @@
|
|||
# ArangoBackup
|
||||
|
||||
## Lifetime
|
||||
|
||||
The Lifetime of an ArangoBackup let us define the time an ArangoBackup is available in the system.
|
||||
E.g.: if we want to keep the ArangoBackup for 1 day, we can set the Lifetime to 1 day. After 1 day the ArangoBackup will be deleted automatically.
|
||||
|
||||
```yaml
|
||||
apiVersion: "backup.arangodb.com/v1alpha"
|
||||
kind: "ArangoBackup"
|
||||
metadata:
|
||||
name: backup-with-one-day-lifetime
|
||||
spec:
|
||||
deployment:
|
||||
name: deployment
|
||||
lifetime: 1d
|
||||
```
|
||||
|
||||
## Upload
|
||||
|
||||
You can upload the backup to a remote storage.
|
||||
Here is an example for uploading the backup to AWS S3.
|
||||
|
||||
```yaml
|
||||
apiVersion: "backup.arangodb.com/v1alpha"
|
||||
kind: "ArangoBackup"
|
||||
metadata:
|
||||
name: backup-and-upload
|
||||
spec:
|
||||
deployment:
|
||||
name: deployment
|
||||
upload:
|
||||
repositoryURL: "s3:BUCKET_NAME"
|
||||
credentialsSecretName: upload-credentials
|
||||
```
|
||||
|
||||
To make this work, you need to create a `upload-credentials` Secret with the credentials for the remote storage:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: upload-credentials
|
||||
type: Opaque
|
||||
stringData:
|
||||
token: |
|
||||
{
|
||||
"s3": {
|
||||
"type": "s3",
|
||||
"provider": "AWS",
|
||||
"env_auth": "false",
|
||||
"region": "eu-central-1",
|
||||
"access_key_id": "ACCESS_KEY_ID",
|
||||
"secret_access_key": "SECRECT_ACCESS_KEY",
|
||||
"acl": "private",
|
||||
"no_check_bucket": "true"
|
||||
}
|
||||
}
|
||||
```
|
|
@ -20,7 +20,7 @@ By default, operator logs in `pretty` format.
|
|||
To switch logging format to the JSON, you can use `operator.args` in chart template value:
|
||||
```yaml
|
||||
operator:
|
||||
args: ["--log.format=pretty"]
|
||||
args: ["--log.format=json"]
|
||||
```
|
||||
|
||||
## ArangoDeployment logging
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
|
||||
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -20,6 +20,8 @@
|
|||
|
||||
package v1
|
||||
|
||||
import meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
type ArangoBackupSpec struct {
|
||||
// Deployment
|
||||
Deployment ArangoBackupSpecDeployment `json:"deployment,omitempty"`
|
||||
|
@ -35,6 +37,9 @@ type ArangoBackupSpec struct {
|
|||
PolicyName *string `json:"policyName,omitempty"`
|
||||
|
||||
Backoff *ArangoBackupSpecBackOff `json:"backoff,omitempty"`
|
||||
|
||||
// Lifetime is the time after which the backup will be deleted. Format: "1.5h" or "2h45m".
|
||||
Lifetime *meta.Duration `json:"lifetime,omitempty"`
|
||||
}
|
||||
|
||||
type ArangoBackupSpecDeployment struct {
|
||||
|
|
|
@ -45,7 +45,7 @@ const (
|
|||
)
|
||||
|
||||
var ArangoBackupStateMap = state.Map{
|
||||
ArangoBackupStateNone: {ArangoBackupStatePending},
|
||||
ArangoBackupStateNone: {ArangoBackupStatePending, ArangoBackupStateFailed},
|
||||
ArangoBackupStatePending: {ArangoBackupStateScheduled, ArangoBackupStateFailed},
|
||||
ArangoBackupStateScheduled: {ArangoBackupStateDownload, ArangoBackupStateCreate, ArangoBackupStateFailed},
|
||||
ArangoBackupStateDownload: {ArangoBackupStateDownloading, ArangoBackupStateFailed, ArangoBackupStateDownloadError},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
|
||||
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -20,7 +20,9 @@
|
|||
|
||||
package v1
|
||||
|
||||
import "github.com/arangodb/kube-arangodb/pkg/util/errors"
|
||||
import (
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/errors"
|
||||
)
|
||||
|
||||
func (a *ArangoBackup) Validate() error {
|
||||
if err := a.Spec.Validate(); err != nil {
|
||||
|
|
5
pkg/apis/backup/v1/zz_generated.deepcopy.go
generated
5
pkg/apis/backup/v1/zz_generated.deepcopy.go
generated
|
@ -284,6 +284,11 @@ func (in *ArangoBackupSpec) DeepCopyInto(out *ArangoBackupSpec) {
|
|||
*out = new(ArangoBackupSpecBackOff)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Lifetime != nil {
|
||||
in, out := &in.Lifetime, &out.Lifetime
|
||||
*out = new(metav1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
|
||||
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -21,6 +21,8 @@
|
|||
package backup
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
|
||||
backupApi "github.com/arangodb/kube-arangodb/pkg/apis/backup/v1"
|
||||
|
@ -56,6 +58,20 @@ func stateReadyHandler(h *handler, backup *backupApi.ArangoBackup) (*backupApi.A
|
|||
)
|
||||
}
|
||||
|
||||
if backup.Spec.Lifetime != nil {
|
||||
if backupMeta.DateTime.Add(backup.Spec.Lifetime.Duration).Before(time.Now()) {
|
||||
err = client.Delete(driver.BackupID(backup.Status.Backup.ID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return wrapUpdateStatus(backup,
|
||||
updateStatusState(backupApi.ArangoBackupStateDeleted, "Backup expired by lifetime"),
|
||||
updateStatusAvailable(false),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
var available = backupMeta.Available
|
||||
|
||||
// Temporally check if number of db servers match number of pieces
|
||||
|
|
|
@ -23,8 +23,10 @@ package backup
|
|||
import (
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/uuid"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
|
@ -66,6 +68,45 @@ func Test_State_Ready_Success(t *testing.T) {
|
|||
compareBackupMeta(t, backupMeta, newObj)
|
||||
}
|
||||
|
||||
func Test_State_Ready_With_Lifetime(t *testing.T) {
|
||||
// Arrange
|
||||
handler, mock := newErrorsFakeHandler(mockErrorsArangoClientBackup{})
|
||||
|
||||
obj, deployment := newObjectSet(backupApi.ArangoBackupStateReady)
|
||||
obj.Spec.Lifetime = &meta.Duration{Duration: 5 * time.Second}
|
||||
|
||||
createResponse, err := mock.Create()
|
||||
require.NoError(t, err)
|
||||
|
||||
backupMeta, err := mock.Get(createResponse.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
obj.Status.Backup = createBackupFromMeta(backupMeta, nil)
|
||||
|
||||
// Act
|
||||
createArangoDeployment(t, handler, deployment)
|
||||
createArangoBackup(t, handler, obj)
|
||||
|
||||
t.Run("First iteration", func(t *testing.T) {
|
||||
require.NoError(t, handler.Handle(newItemFromBackup(operation.Update, obj)))
|
||||
|
||||
// Assert
|
||||
newObj := refreshArangoBackup(t, handler, obj)
|
||||
checkBackup(t, newObj, backupApi.ArangoBackupStateReady, true)
|
||||
compareBackupMeta(t, backupMeta, newObj)
|
||||
})
|
||||
|
||||
t.Run("Second iteration once Lifetime is expired", func(t *testing.T) {
|
||||
time.Sleep(10 * time.Second)
|
||||
require.NoError(t, handler.Handle(newItemFromBackup(operation.Update, obj)))
|
||||
|
||||
// Assert
|
||||
newObj := refreshArangoBackup(t, handler, obj)
|
||||
checkBackup(t, newObj, backupApi.ArangoBackupStateDeleted, false)
|
||||
compareBackupMeta(t, backupMeta, newObj)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_State_Ready_Unavailable(t *testing.T) {
|
||||
// Arrange
|
||||
handler, mock := newErrorsFakeHandler(mockErrorsArangoClientBackup{})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
|
||||
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -61,7 +61,7 @@ func (o *operator) processNextItem() bool {
|
|||
err := o.processObject(obj)
|
||||
|
||||
if err != nil {
|
||||
loggerWorker.Interface("object", obj).Error("Error during object handling")
|
||||
loggerWorker.Interface("object", obj).Error("Error during object handling: %v", err)
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue