diff --git a/test/command/command.go b/test/command/command.go index e2e9f53..430860f 100644 --- a/test/command/command.go +++ b/test/command/command.go @@ -20,17 +20,14 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/config" ) -// RunOptions allows additional options -type RunOptions struct { - IsOutputExpected bool - ExecutePod *corev1.Pod -} - // RunCommandInCluster runs a command in a pod in the cluster and returns the output -func RunCommandInCluster(ctx context.Context, c *kubernetes.Clientset, nodeName string, ns string, command string, log logr.Logger, opts ...*RunOptions) (string, error) { - options := getRunOptions(nodeName, opts) +func RunCommandInCluster(ctx context.Context, c *kubernetes.Clientset, nodeName string, ns string, command string, log logr.Logger, opts ...RunOption) (string, error) { + optionsMap := convertToMap(opts) - pod := options.ExecutePod + pod := getPod(nodeName) + if customizedPod, ok := optionsMap[useCustomizedPod]; ok { + pod = customizedPod.(*corev1.Pod) + } // create a pod and wait that it's running pod, err := c.CoreV1().Pods(ns).Create(ctx, pod, metav1.CreateOptions{}) if err != nil { @@ -46,10 +43,10 @@ func RunCommandInCluster(ctx context.Context, c *kubernetes.Clientset, nodeName log.Info("helper pod is running, going to execute command") cmd := []string{"sh", "-c", command} var bytesResult []byte - if options.IsOutputExpected { - bytesResult, err = waitForPodOutput(ctx, c, pod, cmd) - } else { + if _, ok := optionsMap[noOutputExpected]; ok { bytesResult, err = execCommandOnPod(ctx, c, pod, cmd) + } else { + bytesResult, err = waitForPodOutput(ctx, c, pod, cmd) } if err != nil { @@ -58,24 +55,6 @@ func RunCommandInCluster(ctx context.Context, c *kubernetes.Clientset, nodeName return strings.TrimSpace(string(bytesResult)), nil } -func getRunOptions(nodeName string, opts []*RunOptions) *RunOptions { - defaultOptions := &RunOptions{ - IsOutputExpected: true, - ExecutePod: getPod(nodeName), - } - options := defaultOptions - - if len(opts) > 0 && opts[0] != nil { - userOptions := opts[0] - if userOptions.ExecutePod == nil { - userOptions.ExecutePod = defaultOptions.ExecutePod - } - options = userOptions - - } - return options -} - func waitForPodOutput(ctx context.Context, c *kubernetes.Clientset, pod *corev1.Pod, command []string) ([]byte, error) { var out []byte if err := wait.PollImmediate(1*time.Second, time.Minute, func() (done bool, err error) { diff --git a/test/command/runoptions.go b/test/command/runoptions.go new file mode 100644 index 0000000..13cf671 --- /dev/null +++ b/test/command/runoptions.go @@ -0,0 +1,47 @@ +package command + +import corev1 "k8s.io/api/core/v1" + +type optionType int + +const ( + useCustomizedPod optionType = iota + noOutputExpected +) + +type RunOption interface { + getOptionType() optionType + getOptionValue() interface{} +} + +type runOption struct { + optionType + value interface{} +} + +func (ro *runOption) getOptionType() optionType { + return ro.optionType +} + +func (ro *runOption) getOptionValue() interface{} { + return ro.value +} + +// CreateOptionUseCustomizedExecutePod allows executing a command on a pod provided by this option instead of the default one +func CreateOptionUseCustomizedExecutePod(pod *corev1.Pod) RunOption { + return &runOption{useCustomizedPod, pod} +} + +// CreateOptionNoExpectedOutput allows executing a command on a pod when no output is expected from the command +func CreateOptionNoExpectedOutput() RunOption { + return &runOption{optionType: noOutputExpected} +} + +func convertToMap(opts []RunOption) map[optionType]interface{} { + runOptions := make(map[optionType]interface{}) + for _, option := range opts { + runOptions[option.getOptionType()] = option.getOptionValue() + } + + return runOptions +}