Skip to content

Commit 4e0e00f

Browse files
authored
Merge pull request #473 from red-hat-storage/sync_us--main
Syncing latest changes from upstream main for ramen
2 parents bd3c01e + d662a76 commit 4e0e00f

File tree

6 files changed

+122
-41
lines changed

6 files changed

+122
-41
lines changed
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// SPDX-FileCopyrightText: The RamenDR authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package hooks
5+
6+
import (
7+
"fmt"
8+
9+
"github.com/go-logr/logr"
10+
"github.com/ramendr/ramen/internal/controller/kubeobjects"
11+
"sigs.k8s.io/controller-runtime/pkg/client"
12+
)
13+
14+
type CheckHook struct {
15+
Hook *kubeobjects.HookSpec
16+
}
17+
18+
func (c CheckHook) Execute(client client.Client, log logr.Logger) error {
19+
hookResult, err := EvaluateCheckHook(client, c.Hook, log)
20+
if err != nil {
21+
log.Error(err, "error occurred while evaluating check hook")
22+
23+
return err
24+
}
25+
26+
hookName := c.Hook.Name + "/" + c.Hook.Chk.Name
27+
log.Info("check hook executed successfully", "hook", hookName, "result", hookResult)
28+
29+
if !hookResult && shouldHookBeFailedOnError(c.Hook) {
30+
return fmt.Errorf("stopping workflow as hook %s failed", c.Hook.Name)
31+
}
32+
33+
return nil
34+
}
35+
36+
func shouldHookBeFailedOnError(hook *kubeobjects.HookSpec) bool {
37+
// hook.Check.OnError overwrites the feature of hook.OnError -- defaults to fail
38+
if hook.Chk.OnError != "" && hook.Chk.OnError == "continue" {
39+
return false
40+
}
41+
42+
if hook.OnError != "" && hook.OnError == "continue" {
43+
return false
44+
}
45+
46+
return true
47+
}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// SPDX-FileCopyrightText: The RamenDR authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package hooks
5+
6+
import (
7+
"github.com/go-logr/logr"
8+
"github.com/ramendr/ramen/internal/controller/kubeobjects"
9+
"sigs.k8s.io/controller-runtime/pkg/client"
10+
)
11+
12+
type ExecHook struct {
13+
Hook *kubeobjects.HookSpec
14+
}
15+
16+
func (e ExecHook) Execute(client client.Client, log logr.Logger) error {
17+
return nil
18+
}
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// SPDX-FileCopyrightText: The RamenDR authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package hooks
5+
6+
import (
7+
"fmt"
8+
9+
"github.com/go-logr/logr"
10+
"github.com/ramendr/ramen/internal/controller/kubeobjects"
11+
"sigs.k8s.io/controller-runtime/pkg/client"
12+
)
13+
14+
// Hook interface will help in executing the hooks based on the types.
15+
// Supported types are "check", "scale" and "exec". The implementor needs
16+
// return the result which would be boolean and error if any.
17+
type HookExecutor interface {
18+
Execute(client client.Client, log logr.Logger) error
19+
}
20+
21+
// Based on the hook type, return the appropriate implementation of the hook.
22+
func GetHookExecutor(hook kubeobjects.HookSpec) (HookExecutor, error) {
23+
switch hook.Type {
24+
case "check":
25+
return CheckHook{Hook: &hook}, nil
26+
case "exec":
27+
return ExecHook{Hook: &hook}, nil
28+
default:
29+
return nil, fmt.Errorf("unsupported hook type")
30+
}
31+
}

internal/controller/util/json_util.go internal/controller/hooks/json_util.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-FileCopyrightText: The RamenDR authors
22
// SPDX-License-Identifier: Apache-2.0
33

4-
package util
4+
package hooks
55

66
import (
77
"context"

internal/controller/util/json_util_test.go internal/controller/hooks/json_util_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
// SPDX-FileCopyrightText: The RamenDR authors
22
// SPDX-License-Identifier: Apache-2.0
33

4-
package util_test
4+
package hooks_test
55

66
import (
77
"encoding/json"
88
"strconv"
99
"testing"
1010

11+
"github.com/ramendr/ramen/internal/controller/hooks"
1112
"github.com/ramendr/ramen/internal/controller/kubeobjects"
12-
"github.com/ramendr/ramen/internal/controller/util"
1313
appsv1 "k8s.io/api/apps/v1"
1414
corev1 "k8s.io/api/core/v1"
1515
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -166,7 +166,7 @@ func TestEvaluateCheckHookExp(t *testing.T) {
166166
t.Error(err)
167167
}
168168

169-
_, err = util.EvaluateCheckHookExp(test.jsonPathExprs, jsonData)
169+
_, err = hooks.EvaluateCheckHookExp(test.jsonPathExprs, jsonData)
170170
if (err == nil) != test.result {
171171
t.Errorf("EvaluateCheckHookExp() = %v, want %v", err, test.result)
172172
}
@@ -182,7 +182,7 @@ func TestEvaluateCheckHookForObjects(t *testing.T) {
182182
objs := []client.Object{test.jsonObj}
183183

184184
t.Run(strconv.Itoa(i), func(t *testing.T) {
185-
_, err := util.EvaluateCheckHookForObjects(objs, test.hook, log)
185+
_, err := hooks.EvaluateCheckHookForObjects(objs, test.hook, log)
186186
if (err == nil) != test.result {
187187
t.Errorf("EvaluateCheckHookExpObject() = %v, want %v", err, test.result)
188188
}
@@ -318,7 +318,7 @@ func Test_isValidJsonPathExpression(t *testing.T) {
318318
test := tt
319319

320320
t.Run(test.name, func(t *testing.T) {
321-
if got := util.IsValidJSONPathExpression(test.args.expr); got != test.want {
321+
if got := hooks.IsValidJSONPathExpression(test.args.expr); got != test.want {
322322
t.Errorf("IsValidJSONPathExpression() = %v, want %v", got, test.want)
323323
}
324324
})

internal/controller/vrg_kubeobjects.go

+20-35
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
"github.com/go-logr/logr"
1414
ramen "github.com/ramendr/ramen/api/v1alpha1"
15+
"github.com/ramendr/ramen/internal/controller/hooks"
1516
"github.com/ramendr/ramen/internal/controller/kubeobjects"
1617
"github.com/ramendr/ramen/internal/controller/util"
1718
Recipe "github.com/ramendr/recipe/api/v1alpha1"
@@ -280,7 +281,15 @@ func (v *VRGInstance) executeCaptureSteps(result *ctrl.Result, pathName, capture
280281
isEssentialStep := cg.GroupEssential != nil && *cg.GroupEssential
281282

282283
if cg.IsHook {
283-
err = v.executeHook(cg.Hook, log1)
284+
executor, err1 := hooks.GetHookExecutor(cg.Hook)
285+
if err1 != nil {
286+
// continue if hook type is not supported. Supported types are "check" and "exec"
287+
log1.Info("Hook type not supported", "hook", cg.Hook)
288+
289+
continue
290+
}
291+
292+
err = executor.Execute(v.reconciler.Client, log1)
284293
}
285294

286295
if !cg.IsHook {
@@ -325,39 +334,6 @@ func (v *VRGInstance) executeCaptureSteps(result *ctrl.Result, pathName, capture
325334
return allEssentialStepsFailed, nil
326335
}
327336

328-
func (v *VRGInstance) executeHook(hook kubeobjects.HookSpec, log1 logr.Logger) error {
329-
if hook.Type == "check" {
330-
hookResult, err := util.EvaluateCheckHook(v.reconciler.APIReader, &hook, log1)
331-
if err != nil {
332-
log1.Error(err, "error occurred during check hook ")
333-
} else {
334-
hookName := hook.Name + "/" + hook.Chk.Name
335-
log1.Info("Check hook executed successfully", "check hook is ", hookName, " result is ", hookResult)
336-
}
337-
338-
if !hookResult && shouldHookBeFailedOnError(&hook) {
339-
return fmt.Errorf("stopping workflow sequence as check hook failed")
340-
}
341-
342-
return nil
343-
}
344-
345-
return nil
346-
}
347-
348-
func shouldHookBeFailedOnError(hook *kubeobjects.HookSpec) bool {
349-
// hook.Check.OnError overwrites the feature of hook.OnError -- defaults to fail
350-
if hook.Chk.OnError != "" && hook.Chk.OnError == "continue" {
351-
return false
352-
}
353-
354-
if hook.OnError != "" && hook.OnError == "continue" {
355-
return false
356-
}
357-
358-
return true
359-
}
360-
361337
func (v *VRGInstance) kubeObjectsGroupCapture(
362338
result *ctrl.Result,
363339
captureGroup kubeobjects.CaptureSpec,
@@ -758,6 +734,7 @@ func (v *VRGInstance) kubeObjectsRecoveryStartOrResume(
758734
return v.kubeObjectsRecoverRequestsDelete(result, v.veleroNamespaceName(), labels)
759735
}
760736

737+
// nolint: gocognit,cyclop
761738
func (v *VRGInstance) executeRecoverSteps(result *ctrl.Result, s3StoreAccessor s3StoreAccessor,
762739
captureToRecoverFromIdentifier *ramen.KubeObjectsCaptureIdentifier, captureRequests,
763740
recoverRequests map[string]kubeobjects.Request, requests []kubeobjects.Request, log logr.Logger,
@@ -776,7 +753,15 @@ func (v *VRGInstance) executeRecoverSteps(result *ctrl.Result, s3StoreAccessor s
776753
isEssentialStep := rg.GroupEssential != nil && *rg.GroupEssential
777754

778755
if rg.IsHook {
779-
err = v.executeHook(rg.Hook, log1)
756+
executor, err1 := hooks.GetHookExecutor(rg.Hook)
757+
if err1 != nil {
758+
// continue if hook type is not supported. Supported types are "check" and "exec"
759+
log1.Info("Hook type not supported", "hook", rg.Hook)
760+
761+
continue
762+
}
763+
764+
err = executor.Execute(v.reconciler.Client, log1)
780765
}
781766

782767
if !rg.IsHook {

0 commit comments

Comments
 (0)