Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show a restore point info in the vdb status #942

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 48 additions & 1 deletion pkg/controllers/vdb/saverestorepoint_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ package vdb
import (
"context"
"errors"
"fmt"
"strings"
"time"

"github.com/go-logr/logr"
vapi "github.com/vertica/vertica-kubernetes/api/v1"
"github.com/vertica/vertica-kubernetes/api/v1beta1"
"github.com/vertica/vertica-kubernetes/pkg/controllers"
"github.com/vertica/vertica-kubernetes/pkg/events"
vmeta "github.com/vertica/vertica-kubernetes/pkg/meta"
Expand Down Expand Up @@ -122,12 +124,57 @@ func (s *SaveRestorePointReconciler) Reconcile(ctx context.Context, _ *ctrl.Requ
}
// Once save restore point, change condition
// params: context, host, archive-name, sandbox, num of restore point(0 is unlimited)
return ctrl.Result{}, s.runSaveRestorePointVclusterAPI(ctx, hostIP, vapi.MainCluster)
err := s.runSaveRestorePointVclusterAPI(ctx, hostIP, vapi.MainCluster)
if err != nil {
return ctrl.Result{}, err
}
if !vmeta.GetSkipVRPQCreation(s.Vdb.Annotations) {
s.createVRPQ(ctx)
}
return ctrl.Result{}, nil
}
// archive name param not set correctly, return an error
return ctrl.Result{}, errors.New("create archive failed, archive name not set in restorePoint spec")
}

// createVRPQ creates a VerticaRestorePointsQuery to fetch the restore point info.
func (s *SaveRestorePointReconciler) createVRPQ(ctx context.Context) {
rpq := &v1beta1.VerticaRestorePointsQuery{
TypeMeta: metav1.TypeMeta{
APIVersion: v1beta1.GroupVersion.String(),
Kind: v1beta1.RestorePointsQueryKind,
},
ObjectMeta: metav1.ObjectMeta{
GenerateName: fmt.Sprintf("%s-", s.Vdb.Name),
Namespace: s.Vdb.Namespace,
OwnerReferences: []metav1.OwnerReference{s.Vdb.GenerateOwnerReference()},
},
Spec: v1beta1.VerticaRestorePointsQuerySpec{
VerticaDBName: s.Vdb.Name,
FilterOptions: &v1beta1.VerticaRestorePointQueryFilterOptions{
ArchiveName: s.Vdb.Spec.RestorePoint.Archive,
StartTimestamp: s.Vdb.Status.RestorePoint.StartTimestamp,
EndTimestamp: s.Vdb.Status.RestorePoint.EndTimestamp,
},
},
}
s.Log.Info("Creating a VerticaRestorePointsQuery to show the restore point info")
// We will try this only once, if the operator cannot create the object the user will
// be asked to do it manually. This is because we don't want to fail the reconciler
// just because of it and the users have a few ways to easily get the restore point info
// like creating a vrpq themselves or using vsql.
err := s.VRec.Client.Create(ctx, rpq)
if err != nil {
s.VRec.Eventf(s.Vdb, corev1.EventTypeWarning, events.CreateRestorePointsQueryFailed,
"Failed to create the VerticaRestorePointsQuery %q. Manually create one with filter options from vdb.status.restorepoint"+
" or query archive_restore_points to get the restore point details.",
rpq.GenerateName)
return
}
s.VRec.Eventf(s.Vdb, corev1.EventTypeNormal, events.CreateRestorePointsQuerySucceeded,
"VerticaRestorePointsQuery %s created.", rpq.Name)
}

// runCreateArchiveVclusterAPI will do the actual execution of creating archive.
// This handles logging of necessary events.
func (s *SaveRestorePointReconciler) runCreateArchiveVclusterAPI(ctx context.Context,
Expand Down
194 changes: 98 additions & 96 deletions pkg/events/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,102 +18,104 @@ package events

// Constants for VerticaDB reconciler
const (
AddNodeStart = "AddNodeStart"
AddNodeSucceeded = "AddNodeSucceeded"
AddNodeLicenseFail = "AddNodeLicenseFail"
AddNodeFailed = "AddNodeFailed"
CreateDBStart = "CreateDBStart"
CreateDBSucceeded = "CreateDBSucceeded"
CreateDBFailed = "CreateDBFailed"
ReviveDBStart = "ReviveDBStart"
ReviveDBSucceeded = "ReviveDBSucceeded"
ReviveDBFailed = "ReviveDBFailed"
ReviveDBClusterInUse = "ReviveDBClusterInUse"
ReviveDBNotFound = "ReviveDBNotFound"
ReviveDBPermissionDenied = "ReviveDBPermissionDenied"
ReviveDBNodeCountMismatch = "ReviveDBNodeCountMismatch"
ReviveDBRestoreUnsupported = "ReviveDBRestoreUnsupported"
ReviveDBRestorePointNotFound = "ReviveDBRestorePointNotFound"
ReviveOrderBad = "ReviveOrderBad"
ObjectNotFound = "ObjectNotFound"
CommunalCredsWrongKey = "CommunalCredsWrongKey"
CommunalEndpointIssue = "CommunalEndpointIssue"
S3BucketDoesNotExist = "S3BucketDoesNotExist"
S3WrongRegion = "S3WrongRegion"
S3SseCustomerWrongKey = "S3SseCustomerWrongKey"
InvalidS3SseCustomerKey = "InvalidS3SseCustomerKey"
InvalidConfigParm = "InvalidConfigParm"
CommunalPathIsNotEmpty = "CommunalPathIsNotEmpty"
RemoveNodesStart = "RemoveNodesStart"
RemoveNodesSucceeded = "RemoveNodesSucceeded"
RemoveNodesFailed = "RemoveNodesFailed"
NodeRestartStarted = "NodeRestartStarted"
NodeRestartSucceeded = "NodeRestartSucceeded"
NodeRestartFailed = "NodeRestartFailed"
ClusterRestartStarted = "ClusterRestartStarted"
ClusterRestartSucceeded = "ClusterRestartSucceeded"
SandboxSubclusterFailed = "SandboxSubclusterFailed"
SandboxSubclusterStart = "SandboxSubclusterStart"
SandboxSubclusterSucceeded = "SandboxSubclusterSucceeded"
PromoteSandboxToMainFailed = "PromoteSandboxSubclusterToMainFailed"
PromoteSandboxToMainStart = "PromoteSandboxSubclusterToMainStart"
PromoteSandboxToSucceeded = "PromoteSandboxSubclusterToMainSucceeded"
UnsandboxSubclusterFailed = "UnsandboxSubclusterFailed"
UnsandboxSubclusterStart = "UnsandboxSubclusterStart"
UnsandboxSubclusterSucceeded = "UnsandboxSubclusterSucceeded"
CreateArchiveStart = "CreateArchiveStart"
CreateArchiveSucceeded = "CreateArchiveSucceeded"
ArchiveExists = "ArchiveExists"
CreateArchiveFailed = "CreateArchiveFailed"
SaveRestorePointStart = "SaveRestorePointStart"
SaveRestorePointSucceeded = "SaveRestorePointSucceeded"
SaveRestorePointFailed = "SaveRestorePointFailed"
SlowRestartDetected = "SlowRestartDetected"
SubclusterAdded = "SubclusterAdded"
SubclusterRemoved = "SubclusterRemoved"
AlterSubclusterStart = "AlterSubclusterStart"
AlterSubclusterFailed = "AlterSubclusterFailed"
AlterSubclusterSucceeded = "AlterSubclusterSucceeded"
SuperuserPasswordSecretNotFound = "SuperuserPasswordSecretNotFound"
UnsupportedVerticaVersion = "UnsupportedVerticaVersion"
ATConfPartiallyCopied = "ATConfPartiallyCopied"
AuthParmsCopyFailed = "AuthParmsCopyFailed"
UpgradeStart = "UpgradeStart"
UpgradeSucceeded = "UpgradeSucceeded"
IncompatibleUpgradeRequested = "IncompatibleUpgradeRequested"
ClusterShutdownStarted = "ClusterShutdownStarted"
ClusterShutdownFailed = "ClusterShutdownFailed"
ClusterShutdownSucceeded = "ClusterShutdownSucceeded"
ReipFailed = "ReipFailed"
MissingSecretKeys = "MissingSecretKeys"
HTTPServerNotSetup = "HTTPServerNotSetup"
HTTPServerStartStarted = "HTTPServerStartStarted"
HTTPServerStartFailed = "HTTPServerStartFailed"
KerberosAuthError = "KerberosAuthError"
OperatorUpgrade = "OperatorUpgrade"
InvalidUpgradePath = "InvalidUpgradePath"
RebalanceShards = "RebalanceShards"
DrainNodeRetry = "DrainNodeRetry"
DrainSubclusterRetry = "DrainSubclusterRetry"
SuboptimalNodeCount = "SuboptimalNodeCount"
StopDBStart = "StopDBStart"
StopDBSucceeded = "StopDBSucceeded"
StopDBFailed = "StopDBFailed"
DepotResized = "DepotResized"
MgmtFailed = "MgmtFailed"
MgmtFailedDiskFull = "MgmtFailedDiskfull"
LowLocalDataAvailSpace = "LowLocalDataAvailSpace"
WrongImage = "WrongImage"
MonolithicContainerNotSupported = "MonolithicContainerNotSupported"
InstallPackagesStarted = "InstallPackagesStarted"
InstallPackagesFailed = "InstallPackagesFailed"
InstallPackagesFinished = "InstallPackagesFinished"
RenameSubclusterFailed = "RenameSubclusterFailed"
RenameSubclusterStart = "RenameSubclusterStart"
RenameSubclusterSucceeded = "RenameSubclusterSucceeded"
InDBSaveRestorePointNotSupported = "InDBSaveRestorePointNotSupported"
PauseConnectionsRetry = "PauseConnectionsRetry"
UpgradeFailed = "UpgradeFailed"
AddNodeStart = "AddNodeStart"
AddNodeSucceeded = "AddNodeSucceeded"
AddNodeLicenseFail = "AddNodeLicenseFail"
AddNodeFailed = "AddNodeFailed"
CreateDBStart = "CreateDBStart"
CreateDBSucceeded = "CreateDBSucceeded"
CreateDBFailed = "CreateDBFailed"
ReviveDBStart = "ReviveDBStart"
ReviveDBSucceeded = "ReviveDBSucceeded"
ReviveDBFailed = "ReviveDBFailed"
ReviveDBClusterInUse = "ReviveDBClusterInUse"
ReviveDBNotFound = "ReviveDBNotFound"
ReviveDBPermissionDenied = "ReviveDBPermissionDenied"
ReviveDBNodeCountMismatch = "ReviveDBNodeCountMismatch"
ReviveDBRestoreUnsupported = "ReviveDBRestoreUnsupported"
ReviveDBRestorePointNotFound = "ReviveDBRestorePointNotFound"
ReviveOrderBad = "ReviveOrderBad"
ObjectNotFound = "ObjectNotFound"
CommunalCredsWrongKey = "CommunalCredsWrongKey"
CommunalEndpointIssue = "CommunalEndpointIssue"
S3BucketDoesNotExist = "S3BucketDoesNotExist"
S3WrongRegion = "S3WrongRegion"
S3SseCustomerWrongKey = "S3SseCustomerWrongKey"
InvalidS3SseCustomerKey = "InvalidS3SseCustomerKey"
InvalidConfigParm = "InvalidConfigParm"
CommunalPathIsNotEmpty = "CommunalPathIsNotEmpty"
RemoveNodesStart = "RemoveNodesStart"
RemoveNodesSucceeded = "RemoveNodesSucceeded"
RemoveNodesFailed = "RemoveNodesFailed"
NodeRestartStarted = "NodeRestartStarted"
NodeRestartSucceeded = "NodeRestartSucceeded"
NodeRestartFailed = "NodeRestartFailed"
ClusterRestartStarted = "ClusterRestartStarted"
ClusterRestartSucceeded = "ClusterRestartSucceeded"
SandboxSubclusterFailed = "SandboxSubclusterFailed"
SandboxSubclusterStart = "SandboxSubclusterStart"
SandboxSubclusterSucceeded = "SandboxSubclusterSucceeded"
PromoteSandboxToMainFailed = "PromoteSandboxSubclusterToMainFailed"
PromoteSandboxToMainStart = "PromoteSandboxSubclusterToMainStart"
PromoteSandboxToSucceeded = "PromoteSandboxSubclusterToMainSucceeded"
UnsandboxSubclusterFailed = "UnsandboxSubclusterFailed"
UnsandboxSubclusterStart = "UnsandboxSubclusterStart"
UnsandboxSubclusterSucceeded = "UnsandboxSubclusterSucceeded"
CreateArchiveStart = "CreateArchiveStart"
CreateArchiveSucceeded = "CreateArchiveSucceeded"
ArchiveExists = "ArchiveExists"
CreateArchiveFailed = "CreateArchiveFailed"
SaveRestorePointStart = "SaveRestorePointStart"
SaveRestorePointSucceeded = "SaveRestorePointSucceeded"
SaveRestorePointFailed = "SaveRestorePointFailed"
CreateRestorePointsQueryFailed = "CreateRestorePointsQueryFailed"
CreateRestorePointsQuerySucceeded = "CreateRestorePointsQuerySucceeded"
SlowRestartDetected = "SlowRestartDetected"
SubclusterAdded = "SubclusterAdded"
SubclusterRemoved = "SubclusterRemoved"
AlterSubclusterStart = "AlterSubclusterStart"
AlterSubclusterFailed = "AlterSubclusterFailed"
AlterSubclusterSucceeded = "AlterSubclusterSucceeded"
SuperuserPasswordSecretNotFound = "SuperuserPasswordSecretNotFound"
UnsupportedVerticaVersion = "UnsupportedVerticaVersion"
ATConfPartiallyCopied = "ATConfPartiallyCopied"
AuthParmsCopyFailed = "AuthParmsCopyFailed"
UpgradeStart = "UpgradeStart"
UpgradeSucceeded = "UpgradeSucceeded"
IncompatibleUpgradeRequested = "IncompatibleUpgradeRequested"
ClusterShutdownStarted = "ClusterShutdownStarted"
ClusterShutdownFailed = "ClusterShutdownFailed"
ClusterShutdownSucceeded = "ClusterShutdownSucceeded"
ReipFailed = "ReipFailed"
MissingSecretKeys = "MissingSecretKeys"
HTTPServerNotSetup = "HTTPServerNotSetup"
HTTPServerStartStarted = "HTTPServerStartStarted"
HTTPServerStartFailed = "HTTPServerStartFailed"
KerberosAuthError = "KerberosAuthError"
OperatorUpgrade = "OperatorUpgrade"
InvalidUpgradePath = "InvalidUpgradePath"
RebalanceShards = "RebalanceShards"
DrainNodeRetry = "DrainNodeRetry"
DrainSubclusterRetry = "DrainSubclusterRetry"
SuboptimalNodeCount = "SuboptimalNodeCount"
StopDBStart = "StopDBStart"
StopDBSucceeded = "StopDBSucceeded"
StopDBFailed = "StopDBFailed"
DepotResized = "DepotResized"
MgmtFailed = "MgmtFailed"
MgmtFailedDiskFull = "MgmtFailedDiskfull"
LowLocalDataAvailSpace = "LowLocalDataAvailSpace"
WrongImage = "WrongImage"
MonolithicContainerNotSupported = "MonolithicContainerNotSupported"
InstallPackagesStarted = "InstallPackagesStarted"
InstallPackagesFailed = "InstallPackagesFailed"
InstallPackagesFinished = "InstallPackagesFinished"
RenameSubclusterFailed = "RenameSubclusterFailed"
RenameSubclusterStart = "RenameSubclusterStart"
RenameSubclusterSucceeded = "RenameSubclusterSucceeded"
InDBSaveRestorePointNotSupported = "InDBSaveRestorePointNotSupported"
PauseConnectionsRetry = "PauseConnectionsRetry"
UpgradeFailed = "UpgradeFailed"
)

// Constants for VerticaAutoscaler reconciler
Expand Down
11 changes: 11 additions & 0 deletions pkg/meta/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,11 @@ const (
OnlineUpgradeArchiveBeforeReplicationAnnotation = "vertica.com/online-upgrade-archive-before-replication"

SaveRestorePointAnnotation = "vertica.com/save-restore-point-on-upgrade"
// Allow users to skip the creation of a VerticaRestorePointsQuery object after saving
// a restore point. When this is false, after saving a restore point, the operator
// will create a VerticaRestorePointsQuery in order to expose the restore point info
// the user.
SkipVRPQCreationAnnotation = "vertica.com/skip-restore-points-query-creation"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this annotation? We should always create the VRep CR to collect the restore point's info for the user.


// This will be set in a sandbox configMap by the vdb controller to wake up the sandbox
// controller for upgrading the sandboxes
Expand Down Expand Up @@ -596,6 +601,12 @@ func GetSaveRestorePoint(annotations map[string]string) bool {
return lookupBoolAnnotation(annotations, SaveRestorePointAnnotation, false)
}

// GetSkipVRPQCreation returns true if the operator must create
// a VerticaRestorePointsQuery object after saving a restore point.
func GetSkipVRPQCreation(annotations map[string]string) bool {
return lookupBoolAnnotation(annotations, SkipVRPQCreationAnnotation, true)
}

// GetStsNameOverride returns the override for the statefulset name. If one is
// not provided, an empty string is returned.
func GetStsNameOverride(annotations map[string]string) string {
Expand Down
15 changes: 15 additions & 0 deletions tests/e2e-leg-6/save-restore-point/10-errors.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# (c) Copyright [2021-2024] Open Text.
# 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.

apiVersion: vertica.com/v1beta1
kind: VerticaRestorePointsQuery
20 changes: 20 additions & 0 deletions tests/e2e-leg-6/save-restore-point/12-enable-vrpq-creation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# (c) Copyright [2021-2024] Open Text.
# 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.

apiVersion: vertica.com/v1
kind: VerticaDB
metadata:
name: v-upgrade-vertica
annotations:
vertica.com/vcluster-ops: "true"
vertica.com/skip-restore-points-query-creation: "false"
10 changes: 10 additions & 0 deletions tests/e2e-leg-6/save-restore-point/20-assert.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ involvedObject:
kind: VerticaDB
name: v-restore-point
---
apiVersion: v1
kind: Event
reason: CreateRestorePointsQuerySucceeded
source:
component: verticadb-operator
involvedObject:
apiVersion: vertica.com/v1
kind: VerticaDB
name: v-restore-point
---
apiVersion: vertica.com/v1
kind: VerticaDB
metadata:
Expand Down
20 changes: 20 additions & 0 deletions tests/e2e-leg-6/save-restore-point/25-wait-for-vrpq-creation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# (c) Copyright [2021-2024] Open Text.
# 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.

apiVersion: vertica.com/v1beta1
kind: VerticaRestorePointsQuery
status:
restorePoints:
- archive: test
index: 2
state: "Query successful"
Loading