Repository: submariner-io/submariner-operator
Pull request #1705 (2021-12-13 13:42:19)

Add a status reporter to be used in the subctl lib
Current cli.status implementation does not work well
with the library context of subctl. Hence a new reporter
is added that uses cli.status to report the status.

- Everything from `pkg/internal/*` moved to `internal/*`

Signed-Off-By: Janki Chhatbar <jchhatba@redhat.com>

<!--  Thanks for sending a pull request!  Here are some tips for you:

1. If this is your first time, please read our developer guide: https://submariner.io/development/
2. Ensure you have added the appropriate tests for your PR: https://submariner.io/development/code-review/#test-new-functionality
3. Read the code review guide to ease the review process: https://submariner.io/development/code-review/
4. If the PR is unfinished, mark it as a draft: https://submariner.io/development/code-review/#mark-work-in-progress-prs-as-drafts
5. If you are using CI to debug, use your private fork: https://submariner.io/development/code-review/#use-private-forks-for-debugging-prs-by-running-ci
6. Add labels to the PR as appropriate.

This template is based on the K8s/K8s template:

https://github.com/kubernetes/kubernetes/blob/master/.github/PULL_REQUEST_TEMPLATE.md
-->


submariner-bot: 🤖 Created branch: z_pr1705/Jaanki/new_reporter 
🚀 Full E2E won't run until the "ready-to-test" label is applied. I will add it automatically once the PR has 2 approvals, or you can add it manually.
tpantelis: Re: these linting errors:

```
pkg/deploy/broker.go:98:10: error returned from interface method should be wrapped: sig: func (github.com/submariner-io/submariner-operator/pkg/reporter.Interface).Error(err error, message string, args ...interface{}) error (wrapcheck)
		return reporter.Error(err, "error backing up the brokerfile")
```

We don't need to wrap the return error since it's already wrapped so we can have `wrapcheck` ignore it via adding the pattern `.Error(` to the `ignoreSigs` configuration under `linters-settings` in _.golangci.yml_:

```
  wrapcheck:
    ignoreSigs:
      - .Error(
      - .Errorf(
      - errors.New(
      - errors.Unwrap(
      - .Wrap(
      - .Wrapf(
      - .WithMessage(
      - .WithMessagef(
      - .WithStack(
```

Note: setting `ignoreSigs` will override the defaults so we have to specify all the defaults as well.




tpantelis: @skitt Can you re-review when you get a chance? This is blocking other work.
skitt: I’d rather not keep the “make CI happy” commit separate, so I’ll squash this in the interest of getting the PR merged (given the issues with Quay...).

Patch:
diff --git a/.golangci.yml b/.golangci.yml
index e47cc3ac..f956767b 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -19,6 +19,17 @@ linters-settings:
       - fieldalignment
   lll:
     line-length: 140
+  wrapcheck:
+    ignoreSigs:
+      - .Error(
+      - .Errorf(
+      - errors.New(
+      - errors.Unwrap(
+      - .Wrap(
+      - .Wrapf(
+      - .WithMessage(
+      - .WithMessagef(
+      - .WithStack(
   wsl:
     # Separating explicit var declarations by blank lines seems excessive.
     allow-cuddle-declarations: true
diff --git a/.licenserc.json b/.licenserc.json
index 648615c5..52d905b0 100644
--- a/.licenserc.json
+++ b/.licenserc.json
@@ -22,7 +22,9 @@
 	],
 	"ignore": [
 	    "pkg/client/clientset/",
-	    "pkg/internal/",
+	    "internal/cli",
+		"internal/env",
+		"internal/log",
 	    "vendor/"
 	]
     },
diff --git a/Makefile b/Makefile
index bc735aab..cc9a8e7f 100644
--- a/Makefile
+++ b/Makefile
@@ -55,7 +55,7 @@ override CLUSTERS_ARGS += $(CLUSTER_SETTINGS_FLAG)
 override DEPLOY_ARGS += $(CLUSTER_SETTINGS_FLAG)
 override E2E_ARGS += $(CLUSTER_SETTINGS_FLAG)
 export DEPLOY_ARGS
-override UNIT_TEST_ARGS += cmd pkg/internal
+override UNIT_TEST_ARGS += cmd internal/cli internal/env internal/log
 override VALIDATE_ARGS += --skip-dirs pkg/client
 
 # Process extra flags from the `using=a,b,c` optional flag
diff --git a/cmd/subctl/deploybroker.go b/cmd/subctl/deploybroker.go
index 4faa99da..7d25761f 100644
--- a/cmd/subctl/deploybroker.go
+++ b/cmd/subctl/deploybroker.go
@@ -22,6 +22,7 @@ import (
 	"strings"
 
 	"github.com/spf13/cobra"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/internal/constants"
 	"github.com/submariner-io/submariner-operator/internal/exit"
 	"github.com/submariner-io/submariner-operator/pkg/deploy"
@@ -38,8 +39,7 @@ var deployBroker = &cobra.Command{
 	Use:   "deploy-broker",
 	Short: "Deploys the broker",
 	Run: func(cmd *cobra.Command, args []string) {
-		fmt.Println("deployBroker called")
-		err := deploy.Broker(&deployflags, restConfigProducer)
+		err := deploy.Broker(&deployflags, restConfigProducer, cli.NewReporter())
 		exit.OnError("Error deploying Broker", err)
 	},
 }
diff --git a/cmd/subctl/root.go b/cmd/subctl/root.go
index 3ac4b0b8..4c3fe501 100644
--- a/cmd/subctl/root.go
+++ b/cmd/subctl/root.go
@@ -1,16 +1,21 @@
 /*
 SPDX-License-Identifier: Apache-2.0
+
 Copyright Contributors to the Submariner project.
+
 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.
 */
+
 package subctl
 
 import (
diff --git a/pkg/internal/cli/logger.go b/internal/cli/logger.go
similarity index 97%
rename from pkg/internal/cli/logger.go
rename to internal/cli/logger.go
index edbd5744..9fa81d02 100644
--- a/pkg/internal/cli/logger.go
+++ b/internal/cli/logger.go
@@ -25,8 +25,8 @@ import (
 	"sync"
 	"sync/atomic"
 
-	"github.com/submariner-io/submariner-operator/pkg/internal/env"
-	"github.com/submariner-io/submariner-operator/pkg/internal/log"
+	"github.com/submariner-io/submariner-operator/internal/env"
+	"github.com/submariner-io/submariner-operator/internal/log"
 )
 
 // Logger is the kind cli's log.Logger implementation.
diff --git a/pkg/internal/cli/spinner.go b/internal/cli/spinner.go
similarity index 100%
rename from pkg/internal/cli/spinner.go
rename to internal/cli/spinner.go
diff --git a/pkg/internal/cli/status.go b/internal/cli/status.go
similarity index 71%
rename from pkg/internal/cli/status.go
rename to internal/cli/status.go
index 9d49f964..c3d9bf2f 100644
--- a/pkg/internal/cli/status.go
+++ b/internal/cli/status.go
@@ -20,9 +20,12 @@ import (
 	"fmt"
 	"io"
 	"os"
+	"unicode"
 
-	"github.com/submariner-io/submariner-operator/pkg/internal/env"
-	"github.com/submariner-io/submariner-operator/pkg/internal/log"
+	"github.com/pkg/errors"
+	"github.com/submariner-io/submariner-operator/internal/env"
+	"github.com/submariner-io/submariner-operator/internal/log"
+	"github.com/submariner-io/submariner-operator/pkg/reporter"
 )
 
 type Result int
@@ -86,11 +89,15 @@ func StatusForLogger(l log.Logger) *Status {
 	return s
 }
 
+func NewReporter() reporter.Interface {
+	return NewStatus()
+}
+
 // Start starts a new phase of the status, if attached to a terminal
 // there will be a loading spinner with this status.
-func (s *Status) Start(status string) {
-	s.End(Success)
-	s.status = status
+func (s *Status) Start(message string, args ...interface{}) {
+	s.End()
+	s.status = fmt.Sprintf(message, args...)
 
 	if s.spinner != nil {
 		s.spinner.SetSuffix(fmt.Sprintf(" %s ", s.status))
@@ -100,9 +107,9 @@ func (s *Status) Start(status string) {
 	}
 }
 
-// End completes the current status, ending any previous spinning and
+// EndWith completes the current status, ending any previous spinning and
 // marking the status as success or failure.
-func (s *Status) End(output Result) {
+func (s *Status) EndWith(output Result) {
 	if s.status == "" {
 		return
 	}
@@ -141,17 +148,17 @@ func (s *Status) End(output Result) {
 
 func (s *Status) EndWithFailure(message string, a ...interface{}) {
 	s.QueueFailureMessage(fmt.Sprintf(message, a...))
-	s.End(Failure)
+	s.EndWith(Failure)
 }
 
 func (s *Status) EndWithSuccess(message string, a ...interface{}) {
 	s.QueueSuccessMessage(fmt.Sprintf(message, a...))
-	s.End(Success)
+	s.EndWith(Success)
 }
 
 func (s *Status) EndWithWarning(message string, a ...interface{}) {
 	s.QueueWarningMessage(fmt.Sprintf(message, a...))
-	s.End(Warning)
+	s.EndWith(Warning)
 }
 
 // QueueSuccessMessage queues up a message, which will be displayed once
@@ -166,7 +173,7 @@ func (s *Status) QueueFailureMessage(message string) {
 	s.failureQueue = append(s.failureQueue, message)
 }
 
-// QueuewarningMessage queues up a message, which will be displayed once
+// QueueWarningMessage queues up a message, which will be displayed once
 // the status ends (using the warning format).
 func (s *Status) QueueWarningMessage(message string) {
 	s.warningQueue = append(s.warningQueue, message)
@@ -199,3 +206,50 @@ func CheckForError(err error) Result {
 
 	return Failure
 }
+
+// Failure queues up a message, which will be displayed once
+// the status ends (using the failure format).
+func (s *Status) Failure(message string, a ...interface{}) {
+	if message != "" {
+		s.failureQueue = append(s.failureQueue, fmt.Sprintf(message, a...))
+	}
+}
+
+// Success queues up a message, which will be displayed once
+// the status ends (using the warning format).
+func (s *Status) Success(message string, a ...interface{}) {
+	if message != "" {
+		s.successQueue = append(s.successQueue, fmt.Sprintf(message, a...))
+	}
+}
+
+// Warning queues up a message, which will be displayed once
+// the status ends (using the warning format).
+func (s *Status) Warning(message string, a ...interface{}) {
+	if message != "" {
+		s.warningQueue = append(s.warningQueue, fmt.Sprintf(message, a...))
+	}
+}
+
+func (s *Status) Error(err error, message string, args ...interface{}) error {
+	err = errors.Wrapf(err, message, args...)
+
+	capitalizeFirst := func(str string) string {
+		for i, v := range str {
+			return string(unicode.ToUpper(v)) + str[i+1:]
+		}
+
+		return ""
+	}
+
+	s.Failure(capitalizeFirst(err.Error()))
+	s.End()
+
+	return err
+}
+
+// End completes the current status, ending any previous spinning and
+// marking the status as success or failure.
+func (s *Status) End() {
+	s.EndWith(s.ResultFromMessages())
+}
diff --git a/pkg/internal/log/types.go b/internal/log/types.go
similarity index 100%
rename from pkg/internal/log/types.go
rename to internal/log/types.go
diff --git a/pkg/deploy/broker.go b/pkg/deploy/broker.go
index 13d714af..5a3d4aed 100644
--- a/pkg/deploy/broker.go
+++ b/pkg/deploy/broker.go
@@ -29,7 +29,7 @@ import (
 	"github.com/submariner-io/submariner-operator/internal/restconfig"
 	"github.com/submariner-io/submariner-operator/pkg/broker"
 	"github.com/submariner-io/submariner-operator/pkg/discovery/globalnet"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
+	"github.com/submariner-io/submariner-operator/pkg/reporter"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/components"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/datafile"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/operator/brokercr"
@@ -52,8 +52,10 @@ var ValidComponents = []string{components.ServiceDiscovery, components.Connectiv
 
 const brokerDetailsFilename = "broker-info.subm"
 
-func Broker(options *BrokerOptions, restConfigProducer restconfig.Producer) error {
-	status := cli.NewStatus()
+// Ignoring th cyclic complexity of Broker function because it is being refactored in
+// https://github.com/submariner-io/submariner-operator/pull/1717.
+//gocyclo:ignore
+func Broker(options *BrokerOptions, restConfigProducer restconfig.Producer, status reporter.Interface) error {
 	componentSet := stringset.New(options.BrokerSpec.Components...)
 
 	if err := isValidComponents(componentSet); err != nil {
@@ -73,35 +75,34 @@ func Broker(options *BrokerOptions, restConfigProducer restconfig.Producer) erro
 		return errors.Wrap(err, "the provided kubeconfig is invalid")
 	}
 
-	err = deploy(options, status, config)
-	if err != nil {
+	if err := deploy(options, status, config); err != nil {
 		return err
 	}
 
-	status.Start(fmt.Sprintf("Creating %s file", brokerDetailsFilename))
+	status.Start("Creating %s file", brokerDetailsFilename)
 
 	// If deploy-broker is retried we will attempt to re-use the existing IPsec PSK secret
 	if options.IpsecSubmFile == "" {
 		if _, err := datafile.NewFromFile(brokerDetailsFilename); err == nil {
 			options.IpsecSubmFile = brokerDetailsFilename
-			status.QueueWarningMessage(fmt.Sprintf("Reusing IPsec PSK from existing %s", brokerDetailsFilename))
+			status.Warning("Reusing IPsec PSK from existing %s", brokerDetailsFilename)
 		} else {
-			status.QueueSuccessMessage(fmt.Sprintf("A new IPsec PSK will be generated for %s", brokerDetailsFilename))
+			status.Success("A new IPsec PSK will be generated for %s", brokerDetailsFilename)
 		}
 	}
 
 	subctlData, err := datafile.NewFromCluster(config, options.BrokerNamespace, options.IpsecSubmFile)
 	if err != nil {
-		return errors.Wrap(err, "error retrieving preparing the subm data file")
+		return status.Error(err, "error retrieving preparing the subm data file")
 	}
 
 	newFilename, err := datafile.BackupIfExists(brokerDetailsFilename)
 	if err != nil {
-		return errors.Wrap(err, "error backing up the brokerfile")
+		return status.Error(err, "error backing up the brokerfile")
 	}
 
 	if newFilename != "" {
-		status.QueueSuccessMessage(fmt.Sprintf("Backed up previous %s to %s", brokerDetailsFilename, newFilename))
+		status.Success("Backed up previous %s to %s", brokerDetailsFilename, newFilename)
 	}
 
 	subctlData.ServiceDiscovery = componentSet.Contains(components.ServiceDiscovery)
@@ -123,49 +124,50 @@ func Broker(options *BrokerOptions, restConfigProducer restconfig.Producer) erro
 	}
 
 	err = subctlData.WriteToFile(brokerDetailsFilename)
-	status.End(cli.CheckForError(err))
+	if err != nil {
+		return status.Error(err, "error writing the broker information")
+	}
+
+	status.End()
 
-	return errors.Wrap(err, "error writing the broker information")
+	return nil
 }
 
-func deploy(options *BrokerOptions, status *cli.Status, config *rest.Config) error {
+func deploy(options *BrokerOptions, status reporter.Interface, config *rest.Config) error {
 	status.Start("Setting up broker RBAC")
 
 	err := broker.Ensure(config, options.BrokerSpec.Components, false, options.BrokerNamespace)
-	status.End(cli.CheckForError(err))
-
 	if err != nil {
-		return errors.Wrap(err, "error setting up broker RBAC")
+		return status.Error(err, "error setting up broker RBAC")
 	}
 
+	status.End()
+
 	status.Start("Deploying the Submariner operator")
 
 	operatorImage, err := image.ForOperator(options.ImageVersion, options.Repository, nil)
 	if err != nil {
-		return errors.Wrap(err, "error getting Operator image")
+		return status.Error(err, "error getting Operator image")
 	}
 
 	err = submarinerop.Ensure(status, config, constants.OperatorNamespace, operatorImage, options.OperatorDebug)
-	status.End(cli.CheckForError(err))
-
 	if err != nil {
-		return errors.Wrap(err, "error deploying the operator")
+		return status.Error(err, "error deploying Submariner operator")
 	}
 
+	status.End()
+
 	status.Start("Deploying the broker")
 
 	err = brokercr.Ensure(config, options.BrokerNamespace, options.BrokerSpec)
-	if err == nil {
-		status.QueueSuccessMessage("The broker has been deployed")
-		status.End(cli.Success)
-
-		return nil
+	if err != nil {
+		return status.Error(err, "Broker deployment failed")
 	}
 
-	status.QueueFailureMessage("Broker deployment failed")
-	status.End(cli.Failure)
+	status.Success("The broker has been deployed")
+	status.End()
 
-	return errors.Wrap(err, "error deploying the broker")
+	return nil
 }
 
 func isValidComponents(componentSet stringset.Interface) error {
diff --git a/pkg/discovery/globalnet/globalnet.go b/pkg/discovery/globalnet/globalnet.go
index 29e94454..e1499155 100644
--- a/pkg/discovery/globalnet/globalnet.go
+++ b/pkg/discovery/globalnet/globalnet.go
@@ -26,8 +26,8 @@ import (
 	"net"
 
 	"github.com/pkg/errors"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/broker"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
 	v1 "k8s.io/api/core/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/client-go/kubernetes"
@@ -322,7 +322,7 @@ func ValidateGlobalnetConfiguration(globalnetInfo *Info, netconfig Config) (stri
 		}
 	}
 
-	status.End(cli.Success)
+	status.EndWith(cli.Success)
 
 	return globalnetCIDR, nil
 }
@@ -413,7 +413,7 @@ func AssignGlobalnetIPs(globalnetInfo *Info, netconfig Config) (string, error) {
 		}
 	}
 
-	status.End(cli.Success)
+	status.EndWith(cli.Success)
 
 	return globalnetCIDR, nil
 }
diff --git a/pkg/reporter/reporter.go b/pkg/reporter/reporter.go
new file mode 100644
index 00000000..66fbfb6b
--- /dev/null
+++ b/pkg/reporter/reporter.go
@@ -0,0 +1,40 @@
+/*
+SPDX-License-Identifier: Apache-2.0
+
+Copyright Contributors to the Submariner project.
+
+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.
+*/
+
+package reporter
+
+// Interface for reporting on the progress of an operation.
+type Interface interface {
+	// Start reports that an operation or sequence of operations is starting.
+	Start(message string, args ...interface{})
+
+	// Success reports that the last operation succeeded with the specified message.
+	Success(message string, args ...interface{})
+
+	// Failure reports that the last operation failed with the specified message.
+	Failure(message string, args ...interface{})
+
+	// End the current operation that was previously initiated via Start.
+	End()
+
+	// Warning reports a warning message for the last operation.
+	Warning(message string, args ...interface{})
+
+	// Error wraps err with the supplied message, reports it as a failure, ends the current operation, and returns the error.
+	Error(err error, message string, args ...interface{}) error
+}
diff --git a/pkg/subctl/cmd/cloud/utils/reporter.go b/pkg/subctl/cmd/cloud/utils/reporter.go
index 63c73e33..811ee441 100644
--- a/pkg/subctl/cmd/cloud/utils/reporter.go
+++ b/pkg/subctl/cmd/cloud/utils/reporter.go
@@ -22,7 +22,7 @@ import (
 	"fmt"
 
 	"github.com/submariner-io/cloud-prepare/pkg/api"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 )
 
 type cliReporter struct {
@@ -42,7 +42,7 @@ func (r *cliReporter) Succeeded(message string, args ...interface{}) {
 		r.status.QueueSuccessMessage(fmt.Sprintf(message, args...))
 	}
 
-	r.status.End(cli.Success)
+	r.status.EndWith(cli.Success)
 }
 
 func (r *cliReporter) Failed(err ...error) {
@@ -50,5 +50,5 @@ func (r *cliReporter) Failed(err ...error) {
 		r.status.QueueFailureMessage(err[0].Error())
 	}
 
-	r.status.End(cli.Failure)
+	r.status.EndWith(cli.Failure)
 }
diff --git a/pkg/subctl/cmd/deploybroker.go b/pkg/subctl/cmd/deploybroker.go
index 5e46376f..44749fc4 100644
--- a/pkg/subctl/cmd/deploybroker.go
+++ b/pkg/subctl/cmd/deploybroker.go
@@ -25,10 +25,10 @@ import (
 	"github.com/spf13/cobra"
 	"github.com/submariner-io/admiral/pkg/stringset"
 	submarinerv1a1 "github.com/submariner-io/submariner-operator/api/submariner/v1alpha1"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/internal/image"
 	"github.com/submariner-io/submariner-operator/pkg/broker"
 	"github.com/submariner-io/submariner-operator/pkg/discovery/globalnet"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd/utils"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/components"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/datafile"
@@ -111,24 +111,24 @@ var deployBroker = &cobra.Command{
 
 		status.Start("Setting up broker RBAC")
 		err = broker.Ensure(config, componentArr, false, brokerNamespace)
-		status.End(cli.CheckForError(err))
+		status.EndWith(cli.CheckForError(err))
 		utils.ExitOnError("Error setting up broker RBAC", err)
 
 		status.Start("Deploying the Submariner operator")
 		operatorImage, err := image.ForOperator(imageVersion, repository, nil)
 		utils.ExitOnError("Error overriding Operator Image", err)
 		err = submarinerop.Ensure(status, config, OperatorNamespace, operatorImage, operatorDebug)
-		status.End(cli.CheckForError(err))
+		status.EndWith(cli.CheckForError(err))
 		utils.ExitOnError("Error deploying the operator", err)
 
 		status.Start("Deploying the broker")
 		err = brokercr.Ensure(config, brokerNamespace, populateBrokerSpec())
 		if err == nil {
 			status.QueueSuccessMessage("The broker has been deployed")
-			status.End(cli.Success)
+			status.EndWith(cli.Success)
 		} else {
 			status.QueueFailureMessage("Broker deployment failed")
-			status.End(cli.Failure)
+			status.EndWith(cli.Failure)
 		}
 		utils.ExitOnError("Error deploying the broker", err)
 
@@ -173,7 +173,7 @@ var deployBroker = &cobra.Command{
 		utils.ExitOnError("Error creating globalCIDR configmap on Broker", err)
 
 		err = subctlData.WriteToFile(brokerDetailsFilename)
-		status.End(cli.CheckForError(err))
+		status.EndWith(cli.CheckForError(err))
 		utils.ExitOnError("Error writing the broker information", err)
 	},
 }
diff --git a/pkg/subctl/cmd/diagnose/all.go b/pkg/subctl/cmd/diagnose/all.go
index ecde830f..621b5466 100644
--- a/pkg/subctl/cmd/diagnose/all.go
+++ b/pkg/subctl/cmd/diagnose/all.go
@@ -23,7 +23,7 @@ import (
 
 	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
@@ -47,7 +47,7 @@ func diagnoseAll(cluster *cmd.Cluster) bool {
 	status := cli.NewStatus()
 	if cluster.Submariner == nil {
 		status.Start(cmd.SubmMissingMessage)
-		status.End(cli.Warning)
+		status.EndWith(cli.Warning)
 
 		return success
 	}
diff --git a/pkg/subctl/cmd/diagnose/cni.go b/pkg/subctl/cmd/diagnose/cni.go
index f2fe6bef..ec7efaba 100644
--- a/pkg/subctl/cmd/diagnose/cni.go
+++ b/pkg/subctl/cmd/diagnose/cni.go
@@ -23,7 +23,7 @@ import (
 
 	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd"
 	submv1 "github.com/submariner-io/submariner/pkg/apis/submariner.io/v1"
 	"github.com/submariner-io/submariner/pkg/routeagent_driver/constants"
@@ -60,7 +60,7 @@ func checkCNIConfig(cluster *cmd.Cluster) bool {
 
 	if cluster.Submariner == nil {
 		status.Start(cmd.SubmMissingMessage)
-		status.End(cli.Warning)
+		status.EndWith(cli.Warning)
 
 		return true
 	}
@@ -108,7 +108,7 @@ func checkCalicoIPPoolsIfCalicoCNI(info *cmd.Cluster) bool {
 	found, err := detectCalicoConfigMap(info.KubeClient)
 	if err != nil {
 		status.Start(fmt.Sprintf("Error trying to detect the Calico ConfigMap: %s", err))
-		status.End(cli.Failure)
+		status.EndWith(cli.Failure)
 
 		return false
 	}
@@ -163,7 +163,7 @@ func checkCalicoIPPoolsIfCalicoCNI(info *cmd.Cluster) bool {
 	checkGatewaySubnets(gateways, ippools, status)
 
 	result := status.ResultFromMessages()
-	status.End(result)
+	status.EndWith(result)
 
 	return result != cli.Failure
 }
diff --git a/pkg/subctl/cmd/diagnose/connections.go b/pkg/subctl/cmd/diagnose/connections.go
index 91edfbe7..c793146e 100644
--- a/pkg/subctl/cmd/diagnose/connections.go
+++ b/pkg/subctl/cmd/diagnose/connections.go
@@ -21,7 +21,7 @@ import (
 	"fmt"
 
 	"github.com/spf13/cobra"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd"
 	submv1 "github.com/submariner-io/submariner/pkg/apis/submariner.io/v1"
 )
@@ -42,7 +42,7 @@ func checkConnections(cluster *cmd.Cluster) bool {
 
 	if cluster.Submariner == nil {
 		status.Start(cmd.SubmMissingMessage)
-		status.End(cli.Warning)
+		status.EndWith(cli.Warning)
 
 		return true
 	}
@@ -89,7 +89,7 @@ func checkConnections(cluster *cmd.Cluster) bool {
 	}
 
 	if status.HasFailureMessages() {
-		status.End(cli.Failure)
+		status.EndWith(cli.Failure)
 		return false
 	}
 
diff --git a/pkg/subctl/cmd/diagnose/deployment.go b/pkg/subctl/cmd/diagnose/deployment.go
index 1b90e4e4..2f3bf80a 100644
--- a/pkg/subctl/cmd/diagnose/deployment.go
+++ b/pkg/subctl/cmd/diagnose/deployment.go
@@ -22,7 +22,7 @@ import (
 	"fmt"
 
 	"github.com/spf13/cobra"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd"
 	"github.com/submariner-io/submariner/pkg/cidr"
 	v1 "k8s.io/api/core/v1"
@@ -40,7 +40,7 @@ func init() {
 				if cluster.Submariner == nil {
 					status := cli.NewStatus()
 					status.Start(cmd.SubmMissingMessage)
-					status.End(cli.Warning)
+					status.EndWith(cli.Warning)
 					return true
 				}
 
@@ -98,7 +98,7 @@ func checkOverlappingCIDRs(cluster *cmd.Cluster) bool {
 	}
 
 	if status.HasFailureMessages() {
-		status.End(cli.Failure)
+		status.EndWith(cli.Failure)
 		return false
 	}
 
@@ -132,7 +132,7 @@ func checkPods(cluster *cmd.Cluster) bool {
 	checkPodsStatus(cluster.KubeClient, cmd.OperatorNamespace, status)
 
 	if status.HasFailureMessages() {
-		status.End(cli.Failure)
+		status.EndWith(cli.Failure)
 		return false
 	}
 
diff --git a/pkg/subctl/cmd/diagnose/firewall.go b/pkg/subctl/cmd/diagnose/firewall.go
index 10a9e93f..7a81a846 100644
--- a/pkg/subctl/cmd/diagnose/firewall.go
+++ b/pkg/subctl/cmd/diagnose/firewall.go
@@ -22,7 +22,7 @@ import (
 
 	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/resource"
 	subv1 "github.com/submariner-io/submariner/pkg/apis/submariner.io/v1"
diff --git a/pkg/subctl/cmd/diagnose/firewall_metrics.go b/pkg/subctl/cmd/diagnose/firewall_metrics.go
index 29bfe196..11bfc926 100644
--- a/pkg/subctl/cmd/diagnose/firewall_metrics.go
+++ b/pkg/subctl/cmd/diagnose/firewall_metrics.go
@@ -22,7 +22,7 @@ import (
 	"strings"
 
 	"github.com/spf13/cobra"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd"
 )
 
@@ -102,7 +102,7 @@ func checkFirewallMetricsConfig(cluster *cmd.Cluster) bool {
 	}
 
 	if status.HasFailureMessages() {
-		status.End(cli.Failure)
+		status.EndWith(cli.Failure)
 		return false
 	}
 
diff --git a/pkg/subctl/cmd/diagnose/firewall_tunnel.go b/pkg/subctl/cmd/diagnose/firewall_tunnel.go
index dde51c39..d578b611 100644
--- a/pkg/subctl/cmd/diagnose/firewall_tunnel.go
+++ b/pkg/subctl/cmd/diagnose/firewall_tunnel.go
@@ -24,8 +24,8 @@ import (
 
 	"github.com/spf13/cobra"
 	"github.com/submariner-io/submariner-operator/api/submariner/v1alpha1"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/internal/restconfig"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd/utils"
 	subv1 "github.com/submariner-io/submariner/pkg/apis/submariner.io/v1"
diff --git a/pkg/subctl/cmd/diagnose/firewall_vxlan.go b/pkg/subctl/cmd/diagnose/firewall_vxlan.go
index 14e709f3..ff65b745 100644
--- a/pkg/subctl/cmd/diagnose/firewall_vxlan.go
+++ b/pkg/subctl/cmd/diagnose/firewall_vxlan.go
@@ -22,7 +22,7 @@ import (
 	"strings"
 
 	"github.com/spf13/cobra"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd"
 )
 
@@ -50,7 +50,7 @@ func checkVxLANConfig(cluster *cmd.Cluster) bool {
 
 	if cluster.Submariner == nil {
 		status.Start(cmd.SubmMissingMessage)
-		status.End(cli.Warning)
+		status.EndWith(cli.Warning)
 
 		return true
 	}
@@ -65,7 +65,7 @@ func checkVxLANConfig(cluster *cmd.Cluster) bool {
 	checkFWConfig(cluster, status)
 
 	if status.HasFailureMessages() {
-		status.End(cli.Failure)
+		status.EndWith(cli.Failure)
 		return false
 	}
 
diff --git a/pkg/subctl/cmd/diagnose/k8s_version.go b/pkg/subctl/cmd/diagnose/k8s_version.go
index 0f9dc23f..6e7ebbfc 100644
--- a/pkg/subctl/cmd/diagnose/k8s_version.go
+++ b/pkg/subctl/cmd/diagnose/k8s_version.go
@@ -19,7 +19,7 @@ package diagnose
 
 import (
 	"github.com/spf13/cobra"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd"
 	"github.com/submariner-io/submariner-operator/pkg/version"
 )
@@ -51,7 +51,7 @@ func checkK8sVersion(cluster *cmd.Cluster) bool {
 	}
 
 	if status.HasFailureMessages() {
-		status.End(cli.Failure)
+		status.EndWith(cli.Failure)
 		return false
 	}
 
diff --git a/pkg/subctl/cmd/diagnose/kubeproxy.go b/pkg/subctl/cmd/diagnose/kubeproxy.go
index 5085369a..d2b02282 100644
--- a/pkg/subctl/cmd/diagnose/kubeproxy.go
+++ b/pkg/subctl/cmd/diagnose/kubeproxy.go
@@ -21,7 +21,7 @@ import (
 	"strings"
 
 	"github.com/spf13/cobra"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/resource"
 )
@@ -70,7 +70,7 @@ func checkKubeProxyMode(cluster *cmd.Cluster) bool {
 	}
 
 	result := status.ResultFromMessages()
-	status.End(result)
+	status.EndWith(result)
 
 	return result != cli.Failure
 }
diff --git a/pkg/subctl/cmd/gather/gather.go b/pkg/subctl/cmd/gather/gather.go
index af992a8d..de7adb50 100644
--- a/pkg/subctl/cmd/gather/gather.go
+++ b/pkg/subctl/cmd/gather/gather.go
@@ -26,9 +26,9 @@ import (
 	"time"
 
 	"github.com/spf13/cobra"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/internal/restconfig"
 	subOperatorClientset "github.com/submariner-io/submariner-operator/pkg/client/clientset/versioned"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/names"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd/utils"
@@ -176,7 +176,7 @@ func gatherDataByCluster(cluster *cmd.Cluster, directory string) {
 					info.Status.Start(fmt.Sprintf("Gathering %s %s", module, dataType))
 
 					if gatherFuncs[module](dataType, info) {
-						info.Status.End(info.Status.ResultFromMessages())
+						info.Status.EndWith(info.Status.ResultFromMessages())
 					}
 				}
 			}
diff --git a/pkg/subctl/cmd/gather/types.go b/pkg/subctl/cmd/gather/types.go
index 590cf0ac..b06ffa26 100644
--- a/pkg/subctl/cmd/gather/types.go
+++ b/pkg/subctl/cmd/gather/types.go
@@ -19,7 +19,7 @@ package gather
 
 import (
 	"github.com/submariner-io/submariner-operator/api/submariner/v1alpha1"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	v1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/client-go/dynamic"
diff --git a/pkg/subctl/cmd/join.go b/pkg/subctl/cmd/join.go
index fcfcc03c..412b3880 100644
--- a/pkg/subctl/cmd/join.go
+++ b/pkg/subctl/cmd/join.go
@@ -29,13 +29,13 @@ import (
 	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
 	submariner "github.com/submariner-io/submariner-operator/api/submariner/v1alpha1"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/internal/image"
 	"github.com/submariner-io/submariner-operator/internal/restconfig"
 	"github.com/submariner-io/submariner-operator/pkg/broker"
 	submarinerclientset "github.com/submariner-io/submariner-operator/pkg/client/clientset/versioned"
 	"github.com/submariner-io/submariner-operator/pkg/discovery/globalnet"
 	"github.com/submariner-io/submariner-operator/pkg/discovery/network"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd/utils"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/datafile"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/operator/brokersecret"
@@ -230,7 +230,7 @@ func joinSubmarinerCluster(subctlData *datafile.SubctlData) {
 
 	networkDetails := getNetworkDetails(clientConfig)
 
-	status.End(cli.Success)
+	status.EndWith(cli.Success)
 
 	serviceCIDR, serviceCIDRautoDetected, err := getServiceCIDR(serviceCIDR, networkDetails)
 	utils.ExitOnError("Error determining the service CIDR", err)
@@ -265,13 +265,13 @@ func joinSubmarinerCluster(subctlData *datafile.SubctlData) {
 	operatorImage, err := image.ForOperator(imageVersion, repository, imageOverrideArr)
 	utils.ExitOnError("Error overriding Operator Image", err)
 	err = submarinerop.Ensure(status, clientConfig, OperatorNamespace, operatorImage, operatorDebug)
-	status.End(cli.CheckForError(err))
+	status.EndWith(cli.CheckForError(err))
 	utils.ExitOnError("Error deploying the operator", err)
 
 	status.Start("Creating SA for cluster")
 
 	subctlData.ClientToken, err = broker.CreateSAForCluster(brokerAdminClientset, clusterID, brokerNamespace)
-	status.End(cli.CheckForError(err))
+	status.EndWith(cli.CheckForError(err))
 	utils.ExitOnError("Error creating SA for cluster", err)
 
 	// We need to connect to the broker in all cases
@@ -284,10 +284,10 @@ func joinSubmarinerCluster(subctlData *datafile.SubctlData) {
 		err = submarinercr.Ensure(clientConfig, OperatorNamespace, populateSubmarinerSpec(subctlData, brokerSecret, netconfig))
 		if err == nil {
 			status.QueueSuccessMessage("Submariner is up and running")
-			status.End(cli.Success)
+			status.EndWith(cli.Success)
 		} else {
 			status.QueueFailureMessage("Submariner deployment failed")
-			status.End(cli.Failure)
+			status.EndWith(cli.Failure)
 		}
 
 		utils.ExitOnError("Error deploying Submariner", err)
@@ -296,10 +296,10 @@ func joinSubmarinerCluster(subctlData *datafile.SubctlData) {
 		err = servicediscoverycr.Ensure(clientConfig, OperatorNamespace, populateServiceDiscoverySpec(subctlData, brokerSecret))
 		if err == nil {
 			status.QueueSuccessMessage("Service discovery is up and running")
-			status.End(cli.Success)
+			status.EndWith(cli.Success)
 		} else {
 			status.QueueFailureMessage("Service discovery deployment failed")
-			status.End(cli.Failure)
+			status.EndWith(cli.Failure)
 		}
 		utils.ExitOnError("Error deploying service discovery", err)
 	}
diff --git a/pkg/subctl/cmd/show/all.go b/pkg/subctl/cmd/show/all.go
index 4e359bf4..be27b1fc 100644
--- a/pkg/subctl/cmd/show/all.go
+++ b/pkg/subctl/cmd/show/all.go
@@ -21,7 +21,7 @@ import (
 	"fmt"
 
 	"github.com/spf13/cobra"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd"
 )
 
@@ -43,7 +43,7 @@ func showAll(cluster *cmd.Cluster) bool {
 
 	if cluster.Submariner == nil {
 		status.Start(cmd.SubmMissingMessage)
-		status.End(cli.Warning)
+		status.EndWith(cli.Warning)
 
 		return true
 	}
diff --git a/pkg/subctl/cmd/show/connections.go b/pkg/subctl/cmd/show/connections.go
index 0c68b101..4507f45e 100644
--- a/pkg/subctl/cmd/show/connections.go
+++ b/pkg/subctl/cmd/show/connections.go
@@ -21,7 +21,7 @@ import (
 	"strings"
 
 	"github.com/spf13/cobra"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/table"
 	submv1 "github.com/submariner-io/submariner/pkg/apis/submariner.io/v1"
@@ -93,7 +93,7 @@ func getConnectionsStatus(cluster *cmd.Cluster) bool {
 		return false
 	}
 
-	status.End(cli.Success)
+	status.EndWith(cli.Success)
 	connectionPrinter.Print(connStatus)
 
 	return true
@@ -131,7 +131,7 @@ func showConnections(cluster *cmd.Cluster) bool {
 
 	if cluster.Submariner == nil {
 		status.Start(cmd.SubmMissingMessage)
-		status.End(cli.Warning)
+		status.EndWith(cli.Warning)
 
 		return true
 	}
diff --git a/pkg/subctl/cmd/show/endpoints.go b/pkg/subctl/cmd/show/endpoints.go
index b92f7fa9..ff2bd363 100644
--- a/pkg/subctl/cmd/show/endpoints.go
+++ b/pkg/subctl/cmd/show/endpoints.go
@@ -21,7 +21,7 @@ import (
 	"fmt"
 
 	"github.com/spf13/cobra"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd"
 )
 
@@ -97,7 +97,7 @@ func getEndpointsStatus(cluster *cmd.Cluster) bool {
 		return false
 	}
 
-	status.End(cli.Success)
+	status.EndWith(cli.Success)
 	printEndpoints(epStatus)
 
 	return true
@@ -108,7 +108,7 @@ func showEndpoints(cluster *cmd.Cluster) bool {
 
 	if cluster.Submariner == nil {
 		status.Start(cmd.SubmMissingMessage)
-		status.End(cli.Warning)
+		status.EndWith(cli.Warning)
 
 		return true
 	}
diff --git a/pkg/subctl/cmd/show/gateways.go b/pkg/subctl/cmd/show/gateways.go
index 85285f73..fa7de9da 100644
--- a/pkg/subctl/cmd/show/gateways.go
+++ b/pkg/subctl/cmd/show/gateways.go
@@ -21,7 +21,7 @@ import (
 	"fmt"
 
 	"github.com/spf13/cobra"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd"
 	submv1 "github.com/submariner-io/submariner/pkg/apis/submariner.io/v1"
 )
@@ -98,7 +98,7 @@ func getGatewaysStatus(cluster *cmd.Cluster) bool {
 		return false
 	}
 
-	status.End(cli.Success)
+	status.EndWith(cli.Success)
 	printGateways(gwStatus)
 
 	return true
@@ -109,7 +109,7 @@ func showGateways(cluster *cmd.Cluster) bool {
 
 	if cluster.Submariner == nil {
 		status.Start(cmd.SubmMissingMessage)
-		status.End(cli.Warning)
+		status.EndWith(cli.Warning)
 
 		return true
 	}
diff --git a/pkg/subctl/cmd/show/networks.go b/pkg/subctl/cmd/show/networks.go
index e2d122b3..94bc3349 100644
--- a/pkg/subctl/cmd/show/networks.go
+++ b/pkg/subctl/cmd/show/networks.go
@@ -21,9 +21,9 @@ import (
 	"fmt"
 
 	"github.com/spf13/cobra"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	submarinerclientset "github.com/submariner-io/submariner-operator/pkg/client/clientset/versioned"
 	"github.com/submariner-io/submariner-operator/pkg/discovery/network"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd/utils"
 )
@@ -71,7 +71,7 @@ func showNetwork(cluster *cmd.Cluster) bool {
 	}
 
 	clusterNetwork.Show()
-	status.End(cli.Success)
+	status.EndWith(cli.Success)
 
 	return true
 }
diff --git a/pkg/subctl/cmd/show/versions.go b/pkg/subctl/cmd/show/versions.go
index 79669657..e3413cbe 100644
--- a/pkg/subctl/cmd/show/versions.go
+++ b/pkg/subctl/cmd/show/versions.go
@@ -24,9 +24,9 @@ import (
 	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
 	"github.com/submariner-io/submariner-operator/api/submariner/v1alpha1"
+	"github.com/submariner-io/submariner-operator/internal/cli"
 	submarinerclientset "github.com/submariner-io/submariner-operator/pkg/client/clientset/versioned"
 	"github.com/submariner-io/submariner-operator/pkg/images"
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
 	"github.com/submariner-io/submariner-operator/pkg/names"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/cmd/utils"
@@ -114,7 +114,7 @@ func getVersions(cluster *cmd.Cluster) bool {
 	utils.ExitOnError("Unable to get the Service-Discovery version", err)
 
 	printVersions(versions)
-	status.End(cli.Success)
+	status.EndWith(cli.Success)
 
 	return true
 }
@@ -124,7 +124,7 @@ func showVersions(cluster *cmd.Cluster) bool {
 
 	if cluster.Submariner == nil {
 		status.Start(cmd.SubmMissingMessage)
-		status.End(cli.Warning)
+		status.EndWith(cli.Warning)
 
 		return true
 	}
diff --git a/pkg/subctl/operator/lighthouse/ensure.go b/pkg/subctl/operator/lighthouse/ensure.go
index 52f03cbd..ef227b45 100644
--- a/pkg/subctl/operator/lighthouse/ensure.go
+++ b/pkg/subctl/operator/lighthouse/ensure.go
@@ -19,23 +19,23 @@ limitations under the License.
 package lighthouseop
 
 import (
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
+	"github.com/submariner-io/submariner-operator/pkg/reporter"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/operator/lighthouse/scc"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/operator/lighthouse/serviceaccount"
 	"k8s.io/client-go/rest"
 )
 
-func Ensure(status *cli.Status, config *rest.Config, operatorNamespace string) (bool, error) {
+func Ensure(status reporter.Interface, config *rest.Config, operatorNamespace string) (bool, error) {
 	if created, err := serviceaccount.Ensure(config, operatorNamespace); err != nil {
 		return created, err // nolint:wrapcheck // No need to wrap here
 	} else if created {
-		status.QueueSuccessMessage("Created lighthouse service account and role")
+		status.Success("Created lighthouse service account and role")
 	}
 
 	if created, err := scc.Ensure(config, operatorNamespace); err != nil {
 		return created, err // nolint:wrapcheck // No need to wrap here
 	} else if created {
-		status.QueueSuccessMessage("Updated the privileged SCC")
+		status.Success("Updated the privileged SCC")
 	}
 
 	return true, nil
diff --git a/pkg/subctl/operator/submarinerop/ensure.go b/pkg/subctl/operator/submarinerop/ensure.go
index 3978e309..52c8e105 100644
--- a/pkg/subctl/operator/submarinerop/ensure.go
+++ b/pkg/subctl/operator/submarinerop/ensure.go
@@ -19,9 +19,7 @@ limitations under the License.
 package submarinerop
 
 import (
-	"fmt"
-
-	"github.com/submariner-io/submariner-operator/pkg/internal/cli"
+	"github.com/submariner-io/submariner-operator/pkg/reporter"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/operator/common/namespace"
 	lighthouseop "github.com/submariner-io/submariner-operator/pkg/subctl/operator/lighthouse"
 	"github.com/submariner-io/submariner-operator/pkg/subctl/operator/submarinerop/crds"
@@ -32,41 +30,41 @@ import (
 )
 
 // nolint:wrapcheck // No need to wrap errors here.
-func Ensure(status *cli.Status, config *rest.Config, operatorNamespace, operatorImage string, debug bool) error {
+func Ensure(status reporter.Interface, config *rest.Config, operatorNamespace, operatorImage string, debug bool) error {
 	if created, err := crds.Ensure(config); err != nil {
 		return err
 	} else if created {
-		status.QueueSuccessMessage("Created operator CRDs")
+		status.Success("Created operator CRDs")
 	}
 
 	if created, err := namespace.Ensure(config, operatorNamespace); err != nil {
 		return err
 	} else if created {
-		status.QueueSuccessMessage(fmt.Sprintf("Created operator namespace: %s", operatorNamespace))
+		status.Success("Created operator namespace: %s", operatorNamespace)
 	}
 
 	if created, err := serviceaccount.Ensure(config, operatorNamespace); err != nil {
 		return err
 	} else if created {
-		status.QueueSuccessMessage("Created operator service account and role")
+		status.Success("Created operator service account and role")
 	}
 
 	if created, err := scc.Ensure(config, operatorNamespace); err != nil {
 		return err
 	} else if created {
-		status.QueueSuccessMessage("Updated the privileged SCC")
+		status.Success("Updated the privileged SCC")
 	}
 
 	if created, err := lighthouseop.Ensure(status, config, operatorNamespace); err != nil {
 		return err
 	} else if created {
-		status.QueueSuccessMessage("Created Lighthouse service accounts and roles")
+		status.Success("Created Lighthouse service accounts and roles")
 	}
 
 	if created, err := deployment.Ensure(config, operatorNamespace, operatorImage, debug); err != nil {
 		return err
 	} else if created {
-		status.QueueSuccessMessage("Deployed the operator successfully")
+		status.Success("Deployed the operator successfully")
 	}
 
 	return nil


Test patch:
diff --git a/pkg/internal/env/term.go b/internal/env/term.go
similarity index 100%
rename from pkg/internal/env/term.go
rename to internal/env/term.go
diff --git a/pkg/internal/env/term_test.go b/internal/env/term_test.go
similarity index 95%
rename from pkg/internal/env/term_test.go
rename to internal/env/term_test.go
index c1d88adf..05d4dd22 100644
--- a/pkg/internal/env/term_test.go
+++ b/internal/env/term_test.go
@@ -21,7 +21,7 @@ import (
 	"io/ioutil"
 	"testing"
 
-	"github.com/submariner-io/submariner-operator/pkg/internal/env"
+	"github.com/submariner-io/submariner-operator/internal/env"
 )
 
 func TestIsTerminal(t *testing.T) {