From aea39dddb0c4ab9651e761b2ee7487f3d1c2b1f7 Mon Sep 17 00:00:00 2001 From: Raghavendra Talur Date: Fri, 13 Sep 2024 17:07:45 -0400 Subject: [PATCH] api: make command a single string This is for compatibility with other consumers of recipes. Signed-off-by: Raghavendra Talur Co-Authored-by: Jose A. Rivera --- api/v1alpha1/recipe_types.go | 4 +-- controllers/recipe_controller_test.go | 45 +++++++++++++++++---------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/api/v1alpha1/recipe_types.go b/api/v1alpha1/recipe_types.go index 1c17191..3611046 100644 --- a/api/v1alpha1/recipe_types.go +++ b/api/v1alpha1/recipe_types.go @@ -156,8 +156,8 @@ type Operation struct { // The container where the command should be executed Container string `json:"container,omitempty"` // The command to execute - //+kubebuilder:validation:MinItems=1 - Command []string `json:"command"` + //+kubebuilder:validation:MinLength=1 + Command string `json:"command"` // How to handle command returning with non-zero exit code. Defaults to Fail. OnError string `json:"onError,omitempty"` // How long to wait for the command to execute, in seconds diff --git a/controllers/recipe_controller_test.go b/controllers/recipe_controller_test.go index df0f9bc..fa620d2 100644 --- a/controllers/recipe_controller_test.go +++ b/controllers/recipe_controller_test.go @@ -133,20 +133,19 @@ var _ = Describe("RecipeController", func() { Expect(err).ToNot(BeNil()) }) - echoCommand := func(s string) []string { - return []string{"/bin/sh", "-c", "echo", s} - } - emptyCommand := func(string) []string { - return []string{} + + echoCommandTemplate := "/bin/sh/ -c echo" + emptyCommandTemplate := "" + + commandGenerator := func(commandTemplate, suffix string) string { + return commandTemplate + suffix } - hookOps := func(command func(string) []string, opNames ...string) []*Recipe.Operation { - ops := make([]*Recipe.Operation, len(opNames)) - for i, opName := range opNames { - ops[i] = &Recipe.Operation{Name: opName, Command: command(opName)} - } - return ops + appendOp := func(ops []*Recipe.Operation, opName, commandTemplate, suffix string) []*Recipe.Operation { + op := &Recipe.Operation{Name: opName, Command: commandGenerator(commandTemplate, suffix)} + return append(ops, op) } + hookOpsRecipe := func(ops []*Recipe.Operation) *Recipe.Recipe { return &Recipe.Recipe{ TypeMeta: metav1.TypeMeta{Kind: "Recipe", APIVersion: "ramendr.openshift.io/v1alpha1"}, @@ -164,17 +163,21 @@ var _ = Describe("RecipeController", func() { } } It("error on empty command", func() { - recipe := hookOpsRecipe(hookOps(emptyCommand, "op-1")) + ops := []*Recipe.Operation{} + + ops = appendOp(ops, "op-1", emptyCommandTemplate, "") + + recipe := hookOpsRecipe(ops) Expect(k8sClient.Create(context.TODO(), recipe)).To(MatchError(func() *errors.StatusError { path := field.NewPath("spec", "hooks[0]", "ops[0]", "command") - value := 0 + value := "" return errors.NewInvalid( schema.GroupKind{Group: Recipe.GroupVersion.Group, Kind: "Recipe"}, recipe.Name, field.ErrorList{ field.Invalid( - path, value, validationErrors.TooFewItems( + path, value, validationErrors.TooShort( path.String(), "body", 1, @@ -186,12 +189,22 @@ var _ = Describe("RecipeController", func() { }())) }) It("allow unique Ops names", func() { - err := k8sClient.Create(context.TODO(), hookOpsRecipe(hookOps(echoCommand, "op-1", "op-2"))) + ops := []*Recipe.Operation{} + + ops = appendOp(ops, "op-1", echoCommandTemplate, "aaa") + ops = appendOp(ops, "op-2", echoCommandTemplate, "bbb") + + err := k8sClient.Create(context.TODO(), hookOpsRecipe(ops)) Expect(err).To(BeNil()) }) It("error on duplicate Ops names", func() { - err := k8sClient.Create(context.TODO(), hookOpsRecipe(hookOps(echoCommand, "op-1", "op-1"))) + ops := []*Recipe.Operation{} + + ops = appendOp(ops, "op-1", echoCommandTemplate, "aaa") + ops = appendOp(ops, "op-1", echoCommandTemplate, "bbb") + + err := k8sClient.Create(context.TODO(), hookOpsRecipe(ops)) Expect(err).ToNot(BeNil()) })