github.com/verrazzano/verrazzano@v1.7.0/tools/vz/cmd/install/install_test.go (about)

     1  // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package install
     5  
     6  import (
     7  	"bytes"
     8  	"context"
     9  	"fmt"
    10  	"github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/validators"
    11  	"os"
    12  	"path/filepath"
    13  	"testing"
    14  
    15  	"github.com/spf13/cobra"
    16  	"github.com/stretchr/testify/assert"
    17  	vzconstants "github.com/verrazzano/verrazzano/pkg/constants"
    18  	"github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1alpha1"
    19  	"github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1beta1"
    20  	"github.com/verrazzano/verrazzano/tools/vz/cmd/analyze"
    21  	cmdHelpers "github.com/verrazzano/verrazzano/tools/vz/cmd/helpers"
    22  	"github.com/verrazzano/verrazzano/tools/vz/pkg/constants"
    23  	"github.com/verrazzano/verrazzano/tools/vz/pkg/helpers"
    24  	testhelpers "github.com/verrazzano/verrazzano/tools/vz/test/helpers"
    25  	appsv1 "k8s.io/api/apps/v1"
    26  	corev1 "k8s.io/api/core/v1"
    27  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    28  	"k8s.io/apimachinery/pkg/types"
    29  	"k8s.io/cli-runtime/pkg/genericclioptions"
    30  	dynfake "k8s.io/client-go/dynamic/fake"
    31  	"sigs.k8s.io/controller-runtime/pkg/client"
    32  	"sigs.k8s.io/controller-runtime/pkg/client/fake"
    33  	"sigs.k8s.io/yaml"
    34  )
    35  
    36  const (
    37  	testKubeConfig    = "kubeconfig"
    38  	testK8sContext    = "testcontext"
    39  	testFilenamePath  = "../../test/testdata/v1beta1.yaml"
    40  	BugReportNotExist = "cannot find bug report file in current directory"
    41  )
    42  
    43  // TestInstallCmdDefaultNoWait
    44  // GIVEN a CLI install command with all defaults and --wait==false
    45  //
    46  //	WHEN I call cmd.Execute for install
    47  //	THEN the CLI install command is successful
    48  func TestInstallCmdDefaultNoWait(t *testing.T) {
    49  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateTestVPOObjects()...).Build()
    50  	cmd, _, errBuf, _ := createNewTestCommandAndBuffers(t, c)
    51  	cmd.PersistentFlags().Set(constants.SkipPlatformOperatorFlag, "true")
    52  	cmd.PersistentFlags().Set(constants.WaitFlag, "false")
    53  	cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
    54  	defer cmdHelpers.SetDefaultDeleteFunc()
    55  
    56  	cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil })
    57  	defer cmdHelpers.SetDefaultVPOIsReadyFunc()
    58  
    59  	SetValidateCRFunc(FakeValidateCRFunc)
    60  	defer SetDefaultValidateCRFunc()
    61  
    62  	// Run install command
    63  	err := cmd.Execute()
    64  	assert.NoError(t, err)
    65  	assert.Equal(t, "", errBuf.String())
    66  
    67  	// Verify the vz resource is as expected
    68  	vz := v1alpha1.Verrazzano{}
    69  	err = c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "verrazzano"}, &vz)
    70  	assert.NoError(t, err)
    71  
    72  	expectedLastAppliedConfigAnnotation := "{\"apiVersion\":\"install.verrazzano.io/v1alpha1\",\"kind\":\"Verrazzano\",\"metadata\":{\"annotations\":{},\"name\":\"verrazzano\",\"namespace\":\"default\"}}\n"
    73  	testhelpers.VerifyLastAppliedConfigAnnotation(t, vz.ObjectMeta, expectedLastAppliedConfigAnnotation)
    74  }
    75  
    76  // TestInstallCmdDefaultTimeoutBugReport
    77  // GIVEN a CLI install command with all defaults and --timeout=2ms
    78  //
    79  //	WHEN I call cmd.Execute for install
    80  //	THEN the CLI install command times out and a bug report is generated
    81  func TestInstallCmdDefaultTimeoutBugReport(t *testing.T) {
    82  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateTestVPOObjects()...).Build()
    83  	cmd, buf, errBuf, _ := createNewTestCommandAndBuffers(t, c)
    84  	cmd.PersistentFlags().Set(constants.SkipPlatformOperatorFlag, "true")
    85  	cmd.PersistentFlags().Set(constants.FilenameFlag, testFilenamePath)
    86  	tempKubeConfigPath, _ := os.CreateTemp(os.TempDir(), testKubeConfig)
    87  	cmd.Flags().String(constants.GlobalFlagKubeConfig, tempKubeConfigPath.Name(), "")
    88  	cmd.Flags().String(constants.GlobalFlagContext, testK8sContext, "")
    89  	cmd.PersistentFlags().Set(constants.TimeoutFlag, "2ms")
    90  	cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
    91  	defer cmdHelpers.SetDefaultDeleteFunc()
    92  	defer os.RemoveAll(tempKubeConfigPath.Name())
    93  
    94  	cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil })
    95  	defer cmdHelpers.SetDefaultVPOIsReadyFunc()
    96  
    97  	SetValidateCRFunc(FakeValidateCRFunc)
    98  	defer SetDefaultValidateCRFunc()
    99  
   100  	// Run install command
   101  	err := cmd.Execute()
   102  	assert.Error(t, err)
   103  	assert.Equal(t, "Error: Timeout 2ms exceeded waiting for install to complete\n", errBuf.String())
   104  	assert.Contains(t, buf.String(), "Installing Verrazzano version v1.3.1")
   105  	if !helpers.CheckAndRemoveBugReportExistsInDir("") {
   106  		t.Fatal(BugReportNotExist)
   107  	}
   108  }
   109  
   110  // TestInstallCmdDefaultTimeoutNoBugReport
   111  // GIVEN a CLI install command with --timeout=2ms and auto-bug-report=false
   112  //
   113  //	WHEN I call cmd.Execute for install
   114  //	THEN the CLI install command times out and a bug report is not generated
   115  func TestInstallCmdDefaultTimeoutNoBugReport(t *testing.T) {
   116  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateTestVPOObjects()...).Build()
   117  	cmd, buf, errBuf, _ := createNewTestCommandAndBuffers(t, c)
   118  	cmd.PersistentFlags().Set(constants.SkipPlatformOperatorFlag, "true")
   119  	cmd.PersistentFlags().Set(constants.TimeoutFlag, "2ms")
   120  	cmd.PersistentFlags().Set(constants.FilenameFlag, testFilenamePath)
   121  	tempKubeConfigPath, _ := os.CreateTemp(os.TempDir(), testKubeConfig)
   122  	cmd.Flags().String(constants.GlobalFlagKubeConfig, tempKubeConfigPath.Name(), "")
   123  	cmd.Flags().String(constants.GlobalFlagContext, testK8sContext, "")
   124  	cmd.PersistentFlags().Set(constants.AutoBugReportFlag, "false")
   125  	cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
   126  	defer os.RemoveAll(tempKubeConfigPath.Name())
   127  	defer cmdHelpers.SetDefaultDeleteFunc()
   128  
   129  	cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil })
   130  	defer cmdHelpers.SetDefaultVPOIsReadyFunc()
   131  
   132  	SetValidateCRFunc(FakeValidateCRFunc)
   133  	defer SetDefaultValidateCRFunc()
   134  
   135  	// Run install command
   136  	err := cmd.Execute()
   137  	assert.Error(t, err)
   138  	assert.Equal(t, "Error: Timeout 2ms exceeded waiting for install to complete\n", errBuf.String())
   139  	assert.Contains(t, buf.String(), "Installing Verrazzano version v1.3.1")
   140  	// Bug report must not exist
   141  	if helpers.CheckAndRemoveBugReportExistsInDir("") {
   142  		t.Fatal("found bug report file in current directory")
   143  	}
   144  }
   145  
   146  // TestInstallCmdDefaultNoVPO
   147  // GIVEN a CLI install command with all defaults and no VPO found
   148  //
   149  //	WHEN I call cmd.Execute for install
   150  //	THEN the CLI install command fails and a bug report should be generated
   151  func TestInstallCmdDefaultNoVPO(t *testing.T) {
   152  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).Build()
   153  	cmd, _, errBuf, _ := createNewTestCommandAndBuffers(t, c)
   154  
   155  	// Run install command
   156  	cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
   157  	defer cmdHelpers.SetDefaultDeleteFunc()
   158  	cmd.PersistentFlags().Set(constants.VPOTimeoutFlag, "1s")
   159  	tempKubeConfigPath, _ := os.CreateTemp(os.TempDir(), testKubeConfig)
   160  	cmd.Flags().String(constants.GlobalFlagKubeConfig, tempKubeConfigPath.Name(), "")
   161  	cmd.Flags().String(constants.GlobalFlagContext, testK8sContext, "")
   162  	err := cmd.Execute()
   163  	assert.Error(t, err)
   164  	assert.ErrorContains(t, err, "Waiting for verrazzano-platform-operator pod in namespace verrazzano-install")
   165  	assert.Contains(t, errBuf.String(), "Error: Waiting for verrazzano-platform-operator pod in namespace verrazzano-install")
   166  	if !helpers.CheckAndRemoveBugReportExistsInDir("") {
   167  		t.Fatal(BugReportNotExist)
   168  	}
   169  }
   170  
   171  // TestInstallCmdDefaultMultipleVPO
   172  // GIVEN a CLI install command with all defaults and multiple VPOs found
   173  //
   174  //	WHEN I call cmd.Execute for install
   175  //	THEN the CLI install command fails and a bug report should be generated
   176  func TestInstallCmdDefaultMultipleVPO(t *testing.T) {
   177  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(append(testhelpers.CreateTestVPOObjects(), testhelpers.CreateVPOPod(constants.VerrazzanoPlatformOperator+"-2"))...).Build()
   178  	cmd, _, errBuf, _ := createNewTestCommandAndBuffers(t, c)
   179  
   180  	// Run install command
   181  	cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
   182  	defer cmdHelpers.SetDefaultDeleteFunc()
   183  
   184  	cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil })
   185  	defer cmdHelpers.SetDefaultVPOIsReadyFunc()
   186  
   187  	//cmd.PersistentFlags().Set(constants.SkipPlatformOperatorFlag, "true")
   188  	cmd.PersistentFlags().Set(constants.VPOTimeoutFlag, "1s")
   189  	tempKubeConfigPath, _ := os.CreateTemp(os.TempDir(), testKubeConfig)
   190  	cmd.Flags().String(constants.GlobalFlagKubeConfig, tempKubeConfigPath.Name(), "")
   191  	cmd.Flags().String(constants.GlobalFlagContext, testK8sContext, "")
   192  	cmd.PersistentFlags().Set(constants.SkipConfirmationFlag, "true")
   193  	err := cmd.Execute()
   194  	assert.Error(t, err)
   195  	assert.ErrorContains(t, err, "Waiting for verrazzano-platform-operator, more than one verrazzano-platform-operator pod was found in namespace verrazzano-install")
   196  	assert.Contains(t, errBuf.String(), "Error: Waiting for verrazzano-platform-operator, more than one verrazzano-platform-operator pod was found in namespace verrazzano-install")
   197  	if !helpers.CheckAndRemoveBugReportExistsInDir("") {
   198  		t.Fatal(BugReportNotExist)
   199  	}
   200  }
   201  
   202  // TestInstallCmdJsonLogFormat
   203  // GIVEN a CLI install command with defaults and --log-format=json and --wait==false
   204  //
   205  //	WHEN I call cmd.Execute for install
   206  //	THEN the CLI install command is successful
   207  func TestInstallCmdJsonLogFormat(t *testing.T) {
   208  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateTestVPOObjects()...).Build()
   209  	cmd, _, errBuf, _ := createNewTestCommandAndBuffers(t, c)
   210  	cmd.PersistentFlags().Set(constants.SkipPlatformOperatorFlag, "true")
   211  	cmd.PersistentFlags().Set(constants.LogFormatFlag, "json")
   212  	cmd.PersistentFlags().Set(constants.WaitFlag, "false")
   213  	cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
   214  	defer cmdHelpers.SetDefaultDeleteFunc()
   215  
   216  	cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil })
   217  	defer cmdHelpers.SetDefaultVPOIsReadyFunc()
   218  
   219  	SetValidateCRFunc(FakeValidateCRFunc)
   220  	defer SetDefaultValidateCRFunc()
   221  
   222  	// Run install command
   223  	err := cmd.Execute()
   224  	assert.NoError(t, err)
   225  	assert.Equal(t, "", errBuf.String())
   226  
   227  	// Verify the vz resource is as expected
   228  	vz := v1alpha1.Verrazzano{}
   229  	err = c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "verrazzano"}, &vz)
   230  	assert.NoError(t, err)
   231  }
   232  
   233  // TestInstallCmdMultipleGroupVersions
   234  // GIVEN a CLI install command with defaults and --wait=false and --filename specified and multiple group versions in the filenames
   235  //
   236  //	WHEN I call cmd.Execute for install
   237  //	THEN the CLI install command is unsuccessful but a bug report should not be generated
   238  func TestInstallCmdMultipleGroupVersions(t *testing.T) {
   239  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateTestVPOObjects()...).Build()
   240  	cmd, _, _, _ := createNewTestCommandAndBuffers(t, c)
   241  	cmd.PersistentFlags().Set(constants.FilenameFlag, "../../test/testdata/dev-profile.yaml")
   242  	cmd.PersistentFlags().Set(constants.FilenameFlag, testFilenamePath)
   243  	cmd.PersistentFlags().Set(constants.WaitFlag, "false")
   244  	tempKubeConfigPath, _ := os.CreateTemp(os.TempDir(), testKubeConfig)
   245  	cmd.Flags().String(constants.GlobalFlagKubeConfig, tempKubeConfigPath.Name(), "")
   246  	cmd.Flags().String(constants.GlobalFlagContext, testK8sContext, "")
   247  
   248  	// Run install command
   249  	err := cmd.Execute()
   250  	assert.Error(t, err)
   251  	assert.Contains(t, err.Error(), "cannot merge objects with different group versions")
   252  	if helpers.CheckAndRemoveBugReportExistsInDir("") {
   253  		t.Fatal(BugReportNotExist)
   254  	}
   255  }
   256  
   257  func TestInstallCmdFilenamesV1Beta1(t *testing.T) {
   258  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateTestVPOObjects()...).Build()
   259  	cmd, _, errBuf, _ := createNewTestCommandAndBuffers(t, c)
   260  	cmd.PersistentFlags().Set(constants.SkipPlatformOperatorFlag, "true")
   261  	cmd.PersistentFlags().Set(constants.FilenameFlag, testFilenamePath)
   262  	cmd.PersistentFlags().Set(constants.WaitFlag, "false")
   263  	cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
   264  	defer cmdHelpers.SetDefaultDeleteFunc()
   265  
   266  	cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil })
   267  	defer cmdHelpers.SetDefaultVPOIsReadyFunc()
   268  
   269  	SetValidateCRFunc(FakeValidateCRFunc)
   270  	defer SetDefaultValidateCRFunc()
   271  	// Run install command
   272  	err := cmd.Execute()
   273  	assert.NoError(t, err)
   274  	assert.Equal(t, "", errBuf.String())
   275  
   276  	// Verify the vz resource is as expected
   277  	vz := v1beta1.Verrazzano{}
   278  	err = c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "my-verrazzano"}, &vz)
   279  	assert.NoError(t, err)
   280  	assert.Equal(t, v1beta1.Dev, vz.Spec.Profile)
   281  	assert.NotNil(t, vz.Spec.Components.IngressNGINX)
   282  	assert.NotNil(t, vz.Spec.Components.Fluentd)
   283  	assert.Equal(t, vz.Spec.Components.Fluentd.OpenSearchURL, "https://opensearch.com:9200/")
   284  	assert.Equal(t, vz.Spec.Components.Fluentd.OpenSearchSecret, "foo")
   285  }
   286  
   287  // TestInstallCmdFilenames
   288  // GIVEN a CLI install command with defaults and --wait=false and --filename specified
   289  //
   290  //	WHEN I call cmd.Execute for install
   291  //	THEN the CLI install command is successful
   292  func TestInstallCmdFilenames(t *testing.T) {
   293  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateTestVPOObjects()...).Build()
   294  	cmd, _, errBuf, _ := createNewTestCommandAndBuffers(t, c)
   295  	cmd.PersistentFlags().Set(constants.SkipPlatformOperatorFlag, "true")
   296  	cmd.PersistentFlags().Set(constants.FilenameFlag, "../../test/testdata/dev-profile.yaml")
   297  	cmd.PersistentFlags().Set(constants.WaitFlag, "false")
   298  	cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
   299  	defer cmdHelpers.SetDefaultDeleteFunc()
   300  
   301  	cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil })
   302  	defer cmdHelpers.SetDefaultVPOIsReadyFunc()
   303  	SetValidateCRFunc(FakeValidateCRFunc)
   304  	defer SetDefaultValidateCRFunc()
   305  
   306  	// Run install command
   307  	err := cmd.Execute()
   308  	assert.NoError(t, err)
   309  	assert.Equal(t, "", errBuf.String())
   310  
   311  	// Verify the vz resource is as expected
   312  	vz := v1alpha1.Verrazzano{}
   313  	err = c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "my-verrazzano"}, &vz)
   314  	assert.NoError(t, err)
   315  	assert.Equal(t, v1alpha1.Dev, vz.Spec.Profile)
   316  }
   317  
   318  // TestInstallCmdFilenamesCsv
   319  // GIVEN a CLI install command with defaults and --wait=false and --filename specified as a comma separated list
   320  //
   321  //	WHEN I call cmd.Execute for install
   322  //	THEN the CLI install command is successful
   323  func TestInstallCmdFilenamesCsv(t *testing.T) {
   324  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateTestVPOObjects()...).Build()
   325  	cmd, _, errBuf, _ := createNewTestCommandAndBuffers(t, c)
   326  	cmd.PersistentFlags().Set(constants.SkipPlatformOperatorFlag, "true")
   327  	cmd.PersistentFlags().Set(constants.FilenameFlag, "../../test/testdata/dev-profile.yaml,../../test/testdata/override-components.yaml")
   328  	cmd.PersistentFlags().Set(constants.WaitFlag, "false")
   329  	cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
   330  	defer cmdHelpers.SetDefaultDeleteFunc()
   331  
   332  	cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil })
   333  	defer cmdHelpers.SetDefaultVPOIsReadyFunc()
   334  
   335  	SetValidateCRFunc(FakeValidateCRFunc)
   336  	defer SetDefaultValidateCRFunc()
   337  
   338  	// Run install command
   339  	err := cmd.Execute()
   340  	assert.NoError(t, err)
   341  	assert.Equal(t, "", errBuf.String())
   342  
   343  	// Verify the vz resource is as expected
   344  	vz := v1alpha1.Verrazzano{}
   345  	err = c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "my-verrazzano"}, &vz)
   346  	assert.NoError(t, err)
   347  	assert.Equal(t, v1alpha1.Dev, vz.Spec.Profile)
   348  	assert.False(t, *vz.Spec.Components.Rancher.Enabled)
   349  }
   350  
   351  // TestInstallCmdSets
   352  // GIVEN a CLI install command with defaults and --wait=false and --set specified
   353  //
   354  //	WHEN I call cmd.Execute for install
   355  //	THEN the CLI install command is successful
   356  func TestInstallCmdSets(t *testing.T) {
   357  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateTestVPOObjects()...).Build()
   358  	cmd, _, errBuf, _ := createNewTestCommandAndBuffers(t, c)
   359  	cmd.PersistentFlags().Set(constants.SkipPlatformOperatorFlag, "true")
   360  	cmd.PersistentFlags().Set(constants.SetFlag, "profile=dev")
   361  	cmd.PersistentFlags().Set(constants.SetFlag, "environmentName=test")
   362  	cmd.PersistentFlags().Set(constants.WaitFlag, "false")
   363  	cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
   364  	defer cmdHelpers.SetDefaultDeleteFunc()
   365  
   366  	cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil })
   367  	defer cmdHelpers.SetDefaultVPOIsReadyFunc()
   368  
   369  	SetValidateCRFunc(FakeValidateCRFunc)
   370  	defer SetDefaultValidateCRFunc()
   371  
   372  	// Run install command
   373  	err := cmd.Execute()
   374  	assert.NoError(t, err)
   375  	assert.Equal(t, "", errBuf.String())
   376  
   377  	// Verify the vz resource is as expected
   378  	vz := v1alpha1.Verrazzano{}
   379  	err = c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "verrazzano"}, &vz)
   380  	assert.NoError(t, err)
   381  	assert.Equal(t, v1alpha1.Dev, vz.Spec.Profile)
   382  	assert.Equal(t, "test", vz.Spec.EnvironmentName)
   383  }
   384  
   385  // TestInstallCmdFilenamesAndSets
   386  // GIVEN a CLI install command with defaults and --wait=false and --filename and --set specified
   387  //
   388  //	WHEN I call cmd.Execute for install
   389  //	THEN the CLI install command is successful
   390  func TestInstallCmdFilenamesAndSets(t *testing.T) {
   391  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateTestVPOObjects()...).Build()
   392  	cmd, _, errBuf, _ := createNewTestCommandAndBuffers(t, c)
   393  	cmd.PersistentFlags().Set(constants.SkipPlatformOperatorFlag, "true")
   394  	cmd.PersistentFlags().Set(constants.FilenameFlag, "../../test/testdata/dev-profile.yaml")
   395  	cmd.PersistentFlags().Set(constants.SetFlag, "profile=prod")
   396  	cmd.PersistentFlags().Set(constants.SetFlag, "environmentName=test")
   397  	cmd.PersistentFlags().Set(constants.SetFlag, "components.ingress.overrides[0].values.controller.podLabels.override=\"true\"")
   398  	cmd.PersistentFlags().Set(constants.SetFlag, "components.ingress.overrides[1].values.controller.service.annotations.\"service\\.beta\\.kubernetes\\.io/oci-load-balancer-shape\"=flexible")
   399  	cmd.PersistentFlags().Set(constants.SetFlag, "components.ingress.enabled=true")
   400  	cmd.PersistentFlags().Set(constants.WaitFlag, "false")
   401  	cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
   402  	defer cmdHelpers.SetDefaultDeleteFunc()
   403  
   404  	cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil })
   405  	defer cmdHelpers.SetDefaultVPOIsReadyFunc()
   406  
   407  	SetValidateCRFunc(FakeValidateCRFunc)
   408  	defer SetDefaultValidateCRFunc()
   409  
   410  	// Run install command
   411  	err := cmd.Execute()
   412  	assert.NoError(t, err)
   413  	assert.Equal(t, "", errBuf.String())
   414  
   415  	// Verify the vz resource is as expected
   416  	vz := v1alpha1.Verrazzano{}
   417  	err = c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "my-verrazzano"}, &vz)
   418  	assert.NoError(t, err)
   419  	assert.Equal(t, v1alpha1.Prod, vz.Spec.Profile)
   420  	assert.Equal(t, "test", vz.Spec.EnvironmentName)
   421  	assert.Equal(t, true, *vz.Spec.Components.Ingress.Enabled)
   422  	json, err := vz.Spec.Components.Ingress.InstallOverrides.ValueOverrides[0].Values.MarshalJSON()
   423  	assert.NoError(t, err)
   424  	outyaml, err := yaml.JSONToYAML(json)
   425  	assert.NoError(t, err)
   426  	assert.Equal(t, "controller:\n  podLabels:\n    override: \"true\"\n", string(outyaml))
   427  	json, err = vz.Spec.Components.Ingress.InstallOverrides.ValueOverrides[1].Values.MarshalJSON()
   428  	assert.NoError(t, err)
   429  	outyaml, err = yaml.JSONToYAML(json)
   430  	assert.NoError(t, err)
   431  	assert.Equal(t, "controller:\n  service:\n    annotations:\n      service.beta.kubernetes.io/oci-load-balancer-shape: flexible\n", string(outyaml))
   432  }
   433  
   434  // TestInstallCmdOperatorFile
   435  // GIVEN a CLI install command with defaults and --wait=false and --manifests OR the deprecated --operator-file is specified
   436  //
   437  //	WHEN I call cmd.Execute for install
   438  //	THEN the CLI install command is successful
   439  func TestInstallCmdManifestsFile(t *testing.T) {
   440  	tests := []struct {
   441  		testName          string
   442  		manifestsFlagName string
   443  	}{
   444  		{"Use manifests flag", constants.ManifestsFlag},
   445  		{"Use deprecated operator-file flag", constants.OperatorFileFlag},
   446  	}
   447  	for _, tt := range tests {
   448  		t.Run(tt.testName, func(t *testing.T) {
   449  			c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateTestVPOObjects()...).Build()
   450  			cmd, buf, errBuf, _ := createNewTestCommandAndBuffers(t, c)
   451  			cmd.PersistentFlags().Set(tt.manifestsFlagName, "../../test/testdata/operator-file-fake.yaml")
   452  			cmd.PersistentFlags().Set(constants.WaitFlag, "false")
   453  			cmd.PersistentFlags().Set(constants.SkipConfirmationFlag, "true")
   454  			cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
   455  			defer cmdHelpers.SetDefaultDeleteFunc()
   456  			cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil })
   457  			defer cmdHelpers.SetDefaultVPOIsReadyFunc()
   458  			SetValidateCRFunc(FakeValidateCRFunc)
   459  			defer SetDefaultValidateCRFunc()
   460  
   461  			// Run install command
   462  			err := cmd.Execute()
   463  			assert.NoError(t, err)
   464  			assert.Equal(t, "", errBuf.String())
   465  			assert.Contains(t, buf.String(), "Applying the file ../../test/testdata/operator-file-fake.yaml")
   466  			assert.Contains(t, buf.String(), "namespace/verrazzano-install created")
   467  			assert.Contains(t, buf.String(), "serviceaccount/verrazzano-platform-operator created")
   468  			assert.Contains(t, buf.String(), "service/verrazzano-platform-operator created\n")
   469  
   470  			// Verify the objects in the operator-file got added
   471  			sa := corev1.ServiceAccount{}
   472  			err = c.Get(context.TODO(), types.NamespacedName{Namespace: vzconstants.VerrazzanoInstallNamespace, Name: constants.VerrazzanoPlatformOperator}, &sa)
   473  			assert.NoError(t, err)
   474  
   475  			ns := corev1.Namespace{}
   476  			err = c.Get(context.TODO(), types.NamespacedName{Name: vzconstants.VerrazzanoInstallNamespace}, &ns)
   477  			assert.NoError(t, err)
   478  
   479  			svc := corev1.Service{}
   480  			err = c.Get(context.TODO(), types.NamespacedName{Namespace: vzconstants.VerrazzanoInstallNamespace, Name: constants.VerrazzanoPlatformOperator}, &svc)
   481  			assert.NoError(t, err)
   482  
   483  			// Verify the vz resource is as expected
   484  			vz := v1beta1.Verrazzano{}
   485  			err = c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "verrazzano"}, &vz)
   486  			assert.NoError(t, err)
   487  		})
   488  	}
   489  }
   490  
   491  // TestInstallValidations
   492  // GIVEN an install command
   493  //
   494  //	WHEN invalid command options exist
   495  //	THEN expect an error but a bug report should not be generated
   496  func TestInstallValidations(t *testing.T) {
   497  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateTestVPOObjects()...).Build()
   498  	cmd, _, _, _ := createNewTestCommandAndBuffers(t, c)
   499  	cmd.PersistentFlags().Set(constants.ManifestsFlag, "test")
   500  	cmd.PersistentFlags().Set(constants.VersionFlag, "test")
   501  	tempKubeConfigPath, _ := os.CreateTemp(os.TempDir(), testKubeConfig)
   502  	cmd.Flags().String(constants.GlobalFlagKubeConfig, tempKubeConfigPath.Name(), "")
   503  	cmd.Flags().String(constants.GlobalFlagContext, testK8sContext, "")
   504  	err := cmd.Execute()
   505  	assert.Error(t, err)
   506  	assert.Contains(t, err.Error(), fmt.Sprintf("--%s and --%s cannot both be specified", constants.VersionFlag, constants.ManifestsFlag))
   507  	if helpers.CheckAndRemoveBugReportExistsInDir("") {
   508  		t.Fatal(BugReportNotExist)
   509  	}
   510  
   511  	// test validation for deprecated operator-file flag and version being set
   512  	cmd, _, _, _ = createNewTestCommandAndBuffers(t, c)
   513  	cmd.PersistentFlags().Set(constants.OperatorFileFlag, "test")
   514  	cmd.PersistentFlags().Set(constants.VersionFlag, "test")
   515  	err = cmd.Execute()
   516  	assert.Error(t, err)
   517  	assert.Contains(t, err.Error(), fmt.Sprintf("--%s and --%s cannot both be specified", constants.VersionFlag, constants.ManifestsFlag))
   518  }
   519  
   520  // TestGetWaitTimeoutDefault
   521  // GIVEN no wait and timeout arguments specified
   522  //
   523  //	WHEN I call GetWaitTimeout
   524  //	THEN the default timeout duration is returned
   525  func TestGetWaitTimeoutDefault(t *testing.T) {
   526  	cmd, _, _, _ := createNewTestCommandAndBuffers(t, nil)
   527  	duration, err := cmdHelpers.GetWaitTimeout(cmd, constants.TimeoutFlag)
   528  	assert.NoError(t, err)
   529  	assert.Equal(t, "30m0s", duration.String())
   530  }
   531  
   532  // TestGetWaitTimeoutNoWait
   533  // GIVEN wait is specified as false
   534  //
   535  //	WHEN I call GetWaitTimeout
   536  //	THEN the duration returned is zero
   537  func TestGetWaitTimeoutNoWait(t *testing.T) {
   538  	cmd, _, _, _ := createNewTestCommandAndBuffers(t, nil)
   539  	cmd.PersistentFlags().Set(constants.WaitFlag, "false")
   540  	duration, err := cmdHelpers.GetWaitTimeout(cmd, constants.TimeoutFlag)
   541  	assert.NoError(t, err)
   542  	assert.Equal(t, "0s", duration.String())
   543  }
   544  
   545  // TestGetWaitTimeoutSpecified
   546  // GIVEN wait the timeout is specified as 10m
   547  //
   548  //	WHEN I call GetWaitTimeout
   549  //	THEN the duration returned is 10m0s
   550  func TestGetWaitTimeoutSpecified(t *testing.T) {
   551  	cmd, _, _, _ := createNewTestCommandAndBuffers(t, nil)
   552  	cmd.PersistentFlags().Set(constants.TimeoutFlag, "10m")
   553  	duration, err := cmdHelpers.GetWaitTimeout(cmd, constants.TimeoutFlag)
   554  	assert.NoError(t, err)
   555  	assert.Equal(t, "10m0s", duration.String())
   556  }
   557  
   558  // TestGetLogFormatSimple
   559  // GIVEN simple log format argument specified
   560  //
   561  //	WHEN I call GetLogFormat
   562  //	THEN the simple log format is returned
   563  func TestGetLogFormatSimple(t *testing.T) {
   564  	cmd, _, _, _ := createNewTestCommandAndBuffers(t, nil)
   565  	cmd.PersistentFlags().Set(constants.LogFormatFlag, "simple")
   566  	logFormat, err := cmdHelpers.GetLogFormat(cmd)
   567  	assert.NoError(t, err)
   568  	assert.Equal(t, "simple", logFormat.String())
   569  }
   570  
   571  // TestGetLogFormatJson
   572  // GIVEN json log format is specified
   573  //
   574  //	WHEN I call GetLogFormat
   575  //	THEN json log format is returned
   576  func TestGetLogFormatJson(t *testing.T) {
   577  	cmd, _, _, _ := createNewTestCommandAndBuffers(t, nil)
   578  	cmd.PersistentFlags().Set(constants.LogFormatFlag, "json")
   579  	logFormat, err := cmdHelpers.GetLogFormat(cmd)
   580  	assert.NoError(t, err)
   581  	assert.Equal(t, "json", logFormat.String())
   582  }
   583  
   584  // TestSetCommandInvalidFormat
   585  // GIVEN a set command is specified with the invalid format
   586  //
   587  //	WHEN I call getSetArguments
   588  //	THEN an error is returned
   589  func TestSetCommandInvalidFormat(t *testing.T) {
   590  	cmd, _, errBuf, rc := createNewTestCommandAndBuffers(t, nil)
   591  	cmd.PersistentFlags().Set(constants.SetFlag, "badflag")
   592  	propValues, err := cmdHelpers.GetSetArguments(cmd, rc)
   593  	assert.Nil(t, propValues)
   594  	assert.Error(t, err)
   595  	assert.Equal(t, err.Error(), "Invalid set flag(s) specified")
   596  	assert.Equal(t, "Invalid set flag \"badflag\" specified. Flag must be specified in the format path=value\n", errBuf.String())
   597  }
   598  
   599  // TestSetCommandSingle
   600  // GIVEN a single set command
   601  //
   602  //	WHEN I call getSetArguments
   603  //	THEN the expected property value is returned
   604  func TestSetCommandSingle(t *testing.T) {
   605  	cmd, _, _, rc := createNewTestCommandAndBuffers(t, nil)
   606  	cmd.PersistentFlags().Set(constants.SetFlag, "profile=dev")
   607  	propValues, err := cmdHelpers.GetSetArguments(cmd, rc)
   608  	assert.NoError(t, err)
   609  	assert.Len(t, propValues, 1)
   610  	assert.Contains(t, propValues["spec.profile"], "dev")
   611  }
   612  
   613  // TestSetCommandMultiple
   614  // GIVEN multiple set commands
   615  //
   616  //	WHEN I call getSetArguments
   617  //	THEN the expected property values are returned
   618  func TestSetCommandMultiple(t *testing.T) {
   619  	cmd, _, _, rc := createNewTestCommandAndBuffers(t, nil)
   620  	cmd.PersistentFlags().Set(constants.SetFlag, "profile=dev")
   621  	cmd.PersistentFlags().Set(constants.SetFlag, "spec.environmentName=default")
   622  	propValues, err := cmdHelpers.GetSetArguments(cmd, rc)
   623  	assert.NoError(t, err)
   624  	assert.Len(t, propValues, 2)
   625  	assert.Contains(t, propValues["spec.profile"], "dev")
   626  	assert.Contains(t, propValues["spec.environmentName"], "default")
   627  }
   628  
   629  // TestSetCommandOverride
   630  // GIVEN multiple set commands overriding the same property
   631  //
   632  //	WHEN I call getSetArguments
   633  //	THEN the expected property values are returned
   634  func TestSetCommandOverride(t *testing.T) {
   635  	cmd, _, _, rc := createNewTestCommandAndBuffers(t, nil)
   636  	cmd.PersistentFlags().Set(constants.SetFlag, "profile=dev")
   637  	cmd.PersistentFlags().Set(constants.SetFlag, "profile=prod")
   638  	propValues, err := cmdHelpers.GetSetArguments(cmd, rc)
   639  	assert.NoError(t, err)
   640  	assert.Len(t, propValues, 1)
   641  	assert.Contains(t, propValues["spec.profile"], "prod")
   642  }
   643  
   644  // TestInstallCmdInProgress
   645  // GIVEN a CLI install command when an install was in progress
   646  //
   647  //	WHEN I call cmd.Execute for install
   648  //	THEN the CLI install command is successful
   649  func TestInstallCmdInProgress(t *testing.T) {
   650  	vz := &v1beta1.Verrazzano{
   651  		TypeMeta: metav1.TypeMeta{},
   652  		ObjectMeta: metav1.ObjectMeta{
   653  			Namespace: "default",
   654  			Name:      "verrazzano",
   655  		},
   656  		Status: v1beta1.VerrazzanoStatus{
   657  			State:   v1beta1.VzStateReconciling,
   658  			Version: "v1.3.1",
   659  		},
   660  	}
   661  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(append(testhelpers.CreateTestVPOObjects(), vz)...).Build()
   662  	cmd, _, errBuf, _ := createNewTestCommandAndBuffers(t, c)
   663  	cmd.PersistentFlags().Set(constants.WaitFlag, "false")
   664  	cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
   665  	defer cmdHelpers.SetDefaultDeleteFunc()
   666  
   667  	cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil })
   668  	defer cmdHelpers.SetDefaultVPOIsReadyFunc()
   669  	defer ensureResourcesDeleted(t, c)
   670  
   671  	// Run install command
   672  	err := cmd.Execute()
   673  	assert.NoError(t, err)
   674  	assert.Equal(t, "", errBuf.String())
   675  }
   676  
   677  // TestInstallCmdAlreadyInstalled
   678  // GIVEN a CLI install command when an install already happened
   679  //
   680  //	WHEN I call cmd.Execute for install
   681  //	THEN the CLI install command is unsuccessful but a bug report is not generated
   682  func TestInstallCmdAlreadyInstalled(t *testing.T) {
   683  	vz := &v1beta1.Verrazzano{
   684  		TypeMeta: metav1.TypeMeta{},
   685  		ObjectMeta: metav1.ObjectMeta{
   686  			Namespace: "default",
   687  			Name:      "verrazzano",
   688  		},
   689  		Status: v1beta1.VerrazzanoStatus{
   690  			State:   v1beta1.VzStateReady,
   691  			Version: "v1.3.1",
   692  		},
   693  	}
   694  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(append(testhelpers.CreateTestVPOObjects(), vz)...).Build()
   695  	cmd, _, _, _ := createNewTestCommandAndBuffers(t, c)
   696  	cmd.PersistentFlags().Set(constants.WaitFlag, "false")
   697  	tempKubeConfigPath, _ := os.CreateTemp(os.TempDir(), testKubeConfig)
   698  	cmd.Flags().String(constants.GlobalFlagKubeConfig, tempKubeConfigPath.Name(), "")
   699  	cmd.Flags().String(constants.GlobalFlagContext, testK8sContext, "")
   700  	cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
   701  	defer cmdHelpers.SetDefaultDeleteFunc()
   702  
   703  	cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil })
   704  	defer cmdHelpers.SetDefaultVPOIsReadyFunc()
   705  
   706  	// Run install command
   707  	err := cmd.Execute()
   708  	assert.Error(t, err)
   709  	assert.Contains(t, err.Error(), "Only one install of Verrazzano is allowed")
   710  	if helpers.CheckAndRemoveBugReportExistsInDir("") {
   711  		t.Fatal(BugReportNotExist)
   712  	}
   713  }
   714  
   715  // TestInstallCmdDifferentVersion
   716  // GIVEN a CLI install command when an install is in progress for a different version
   717  //
   718  //	WHEN I call cmd.Execute for install
   719  //	THEN the CLI install command is unsuccessful but a bug report is not generated
   720  func TestInstallCmdDifferentVersion(t *testing.T) {
   721  	vz := &v1beta1.Verrazzano{
   722  		TypeMeta: metav1.TypeMeta{},
   723  		ObjectMeta: metav1.ObjectMeta{
   724  			Namespace: "default",
   725  			Name:      "verrazzano",
   726  		},
   727  		Status: v1beta1.VerrazzanoStatus{
   728  			State:   v1beta1.VzStateReconciling,
   729  			Version: "v1.3.2",
   730  		},
   731  	}
   732  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(append(testhelpers.CreateTestVPOObjects(), vz)...).Build()
   733  	cmd, _, _, _ := createNewTestCommandAndBuffers(t, c)
   734  	cmd.PersistentFlags().Set(constants.WaitFlag, "false")
   735  	tempKubeConfigPath, _ := os.CreateTemp(os.TempDir(), testKubeConfig)
   736  	cmd.Flags().String(constants.GlobalFlagKubeConfig, tempKubeConfigPath.Name(), "")
   737  	cmd.Flags().String(constants.GlobalFlagContext, testK8sContext, "")
   738  	cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
   739  	defer cmdHelpers.SetDefaultDeleteFunc()
   740  
   741  	cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil })
   742  	defer cmdHelpers.SetDefaultVPOIsReadyFunc()
   743  
   744  	// Run install command
   745  	err := cmd.Execute()
   746  	assert.Error(t, err)
   747  	assert.Contains(t, err.Error(), "Unable to install version v1.3.1, install of version v1.3.2 is in progress")
   748  	if helpers.CheckAndRemoveBugReportExistsInDir("") {
   749  		t.Fatal(BugReportNotExist)
   750  	}
   751  }
   752  
   753  func createNewTestCommandAndBuffers(t *testing.T, c client.Client) (*cobra.Command, *bytes.Buffer, *bytes.Buffer, *testhelpers.FakeRootCmdContext) {
   754  	buf := new(bytes.Buffer)
   755  	errBuf := new(bytes.Buffer)
   756  
   757  	rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf})
   758  	if c != nil {
   759  		rc.SetClient(c)
   760  	}
   761  	rc.SetDynamicClient(dynfake.NewSimpleDynamicClient(helpers.GetScheme()))
   762  
   763  	cmd := NewCmdInstall(rc)
   764  	assert.NotNil(t, cmd)
   765  	return cmd, buf, errBuf, rc
   766  }
   767  
   768  // installVZ installs Verrazzano using the given client
   769  func installVZ(t *testing.T, c client.WithWatch) {
   770  	stdoutFile, stderrFile := createStdTempFiles(t)
   771  	defer func() {
   772  		os.Remove(stdoutFile.Name())
   773  		os.Remove(stderrFile.Name())
   774  	}()
   775  	rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile})
   776  	rc.SetClient(c)
   777  	cmd := NewCmdInstall(rc)
   778  	assert.NotNil(t, cmd)
   779  	cmd.PersistentFlags().Set(constants.WaitFlag, "false")
   780  	cmd.PersistentFlags().Set(constants.VersionFlag, "v1.4.0")
   781  	cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
   782  	defer cmdHelpers.SetDefaultDeleteFunc()
   783  
   784  	cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil })
   785  	defer cmdHelpers.SetDefaultVPOIsReadyFunc()
   786  
   787  	// Run install command
   788  	err := cmd.Execute()
   789  	assert.NoError(t, err)
   790  	buf, err := os.ReadFile(stderrFile.Name())
   791  	assert.NoError(t, err)
   792  	assert.Equal(t, "", string(buf))
   793  }
   794  
   795  // createStdTempFiles creates temporary files for stdout and stderr.
   796  func createStdTempFiles(t *testing.T) (*os.File, *os.File) {
   797  	stdoutFile, err := os.CreateTemp("", "tmpstdout")
   798  	assert.NoError(t, err)
   799  
   800  	stderrFile, err := os.CreateTemp("", "tmpstderr")
   801  	assert.NoError(t, err)
   802  
   803  	return stdoutFile, stderrFile
   804  }
   805  
   806  // TestAnalyzeCommandDefault
   807  // GIVEN a CLI analyze command
   808  // WHEN I call cmd.Execute without specifying flag capture-dir
   809  // THEN expect the command to analyze the live cluster
   810  func TestAnalyzeCommandDefault(t *testing.T) {
   811  	c := getClientWithWatch()
   812  	SetValidateCRFunc(FakeValidateCRFunc)
   813  	defer SetDefaultValidateCRFunc()
   814  	installVZ(t, c)
   815  
   816  	// Verify the vz resource is as expected
   817  	vz := v1beta1.Verrazzano{}
   818  	err := c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "verrazzano"}, &vz)
   819  	assert.NoError(t, err)
   820  
   821  	stdoutFile, stderrFile := createStdTempFiles(t)
   822  	defer func() {
   823  		os.Remove(stdoutFile.Name())
   824  		os.Remove(stderrFile.Name())
   825  	}()
   826  	rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: stdoutFile, ErrOut: stderrFile})
   827  	rc.SetClient(c)
   828  	rc.SetDynamicClient(dynfake.NewSimpleDynamicClient(helpers.GetScheme()))
   829  
   830  	cmd := analyze.NewCmdAnalyze(rc)
   831  	cmd.PersistentFlags().Set(constants.SkipPlatformOperatorFlag, "true")
   832  	assert.NotNil(t, cmd)
   833  	err = cmd.Execute()
   834  	assert.Nil(t, err)
   835  	buf, err := os.ReadFile(stdoutFile.Name())
   836  	assert.NoError(t, err)
   837  	// This should generate a stdout from the live cluster
   838  	assert.Contains(t, string(buf), "Verrazzano analysis CLI did not detect any issue in")
   839  	// Clean analysis should not generate a report file
   840  	fileMatched, _ := filepath.Glob(constants.VzAnalysisReportTmpFile)
   841  	assert.Len(t, fileMatched, 0)
   842  }
   843  
   844  // getClientWithWatch returns a client for installing Verrazzano
   845  func getClientWithWatch() client.WithWatch {
   846  	vpo := &corev1.Pod{
   847  		ObjectMeta: metav1.ObjectMeta{
   848  			Namespace: vzconstants.VerrazzanoInstallNamespace,
   849  			Name:      constants.VerrazzanoPlatformOperator,
   850  			Labels: map[string]string{
   851  				"app":               constants.VerrazzanoPlatformOperator,
   852  				"pod-template-hash": "45f78ffddd",
   853  			},
   854  		},
   855  	}
   856  	deployment := &appsv1.Deployment{
   857  		ObjectMeta: metav1.ObjectMeta{
   858  			Namespace: vzconstants.VerrazzanoInstallNamespace,
   859  			Name:      constants.VerrazzanoPlatformOperator,
   860  		},
   861  		Spec: appsv1.DeploymentSpec{
   862  			Selector: &metav1.LabelSelector{
   863  				MatchLabels: map[string]string{"app": constants.VerrazzanoPlatformOperator},
   864  			},
   865  		},
   866  		Status: appsv1.DeploymentStatus{
   867  			AvailableReplicas: 1,
   868  			UpdatedReplicas:   1,
   869  		},
   870  	}
   871  	replicaset := &appsv1.ReplicaSet{
   872  		ObjectMeta: metav1.ObjectMeta{
   873  			Namespace: vzconstants.VerrazzanoInstallNamespace,
   874  			Name:      fmt.Sprintf("%s-45f78ffddd", constants.VerrazzanoPlatformOperator),
   875  			Annotations: map[string]string{
   876  				"deployment.kubernetes.io/revision": "1",
   877  			},
   878  		},
   879  	}
   880  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(vpo, deployment, replicaset).Build()
   881  	return c
   882  }
   883  
   884  // TestInstallFromPrivateRegistry tests installing from a private registry.
   885  //
   886  // GIVEN a CLI install command with private registry flags set
   887  //
   888  //	WHEN I call cmd.Execute for install
   889  //	THEN the CLI install command is successful and the VPO and VPO webhook deployments have the expected private registry configuration
   890  func TestInstallFromPrivateRegistry(t *testing.T) {
   891  	const imageRegistry = "testreg.io"
   892  	const imagePrefix = "testrepo"
   893  
   894  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateTestVPOObjects()...).Build()
   895  	cmd, _, errBuf, _ := createNewTestCommandAndBuffers(t, c)
   896  	cmd.PersistentFlags().Set(constants.WaitFlag, "false")
   897  	cmd.PersistentFlags().Set(constants.ImageRegistryFlag, imageRegistry)
   898  	cmd.PersistentFlags().Set(constants.ImagePrefixFlag, imagePrefix)
   899  	cmd.PersistentFlags().Set(constants.SkipConfirmationFlag, "true")
   900  	cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
   901  	defer cmdHelpers.SetDefaultDeleteFunc()
   902  
   903  	cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil })
   904  	defer cmdHelpers.SetDefaultVPOIsReadyFunc()
   905  
   906  	SetValidateCRFunc(FakeValidateCRFunc)
   907  	defer SetDefaultValidateCRFunc()
   908  
   909  	// Run install command
   910  	err := cmd.Execute()
   911  	assert.NoError(t, err)
   912  	assert.Equal(t, "", errBuf.String())
   913  
   914  	// Verify that the VPO deployment has the expected environment variables to enable pulling images from a private registry
   915  	deployment, err := cmdHelpers.GetExistingVPODeployment(c)
   916  	assert.NoError(t, err)
   917  	assert.NotNil(t, deployment)
   918  	testhelpers.AssertPrivateRegistryEnvVars(t, c, deployment, imageRegistry, imagePrefix)
   919  
   920  	// Verify that the VPO image has been updated
   921  	testhelpers.AssertPrivateRegistryImage(t, c, deployment, imageRegistry, imagePrefix)
   922  
   923  	// Verify that the VPO webhook image has been updated
   924  	deployment, err = cmdHelpers.GetExistingVPOWebhookDeployment(c)
   925  	assert.NoError(t, err)
   926  	assert.NotNil(t, deployment)
   927  
   928  	testhelpers.AssertPrivateRegistryImage(t, c, deployment, imageRegistry, imagePrefix)
   929  }
   930  
   931  // TestInstallFromFilename tests installing from a filename.
   932  //
   933  // GIVEN a filename after install command with filename flags set
   934  //
   935  //	WHEN I call cmd.Execute for install
   936  //	THEN the CLI install command fails and should catch the missing filename flag or the missing file
   937  func TestInstallFromFilename(t *testing.T) {
   938  	c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).Build()
   939  	cmd, _, errBuf, rc := createNewTestCommandAndBuffers(t, c)
   940  
   941  	cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
   942  	defer cmdHelpers.SetDefaultDeleteFunc()
   943  
   944  	cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil })
   945  	defer cmdHelpers.SetDefaultVPOIsReadyFunc()
   946  
   947  	SetValidateCRFunc(FakeValidateCRFunc)
   948  	defer SetDefaultValidateCRFunc()
   949  
   950  	// Send stdout stderr to a byte bufferF
   951  	rc.SetClient(c)
   952  
   953  	os.Args = append(os.Args, testFilenamePath)
   954  	err := cmd.Execute()
   955  	if err != nil {
   956  		return
   957  	}
   958  	assert.Contains(t, errBuf.String(), "Error: invalid arguments specified:")
   959  	//Clean the resource args for further test cases.
   960  	s := len(os.Args)
   961  	os.Args = append(os.Args[:s-1])
   962  }
   963  
   964  // TestInstallSkipOperatorInstall tests installing Verrazzano and skipping the install of the operator.
   965  //
   966  // GIVEN a CLI install command with skip-operator-install flags set
   967  //
   968  //	WHEN I call cmd.Execute for install
   969  //	THEN the CLI install command is successful and the VPO and VPO webhook deployments do not get reinstalled
   970  func TestInstallSkipOperatorInstall(t *testing.T) {
   971  	tests := []struct {
   972  		name         string
   973  		skipInstall  bool
   974  		vpoExists    bool
   975  		cmdLineInput string
   976  	}{
   977  		{name: "VPO is already running, skip-platform-operator enabled", skipInstall: true, vpoExists: true},
   978  		{name: "VPO is already running, skip-platform-operator disabled, reInstallVPO-y", skipInstall: false, vpoExists: true, cmdLineInput: "y"},
   979  		{name: "VPO is already running, skip-platform-operator disabled, reInstallVPO-n", skipInstall: false, vpoExists: true, cmdLineInput: "n"},
   980  		{name: "VPO is already running, reinstall", skipInstall: false, vpoExists: true, cmdLineInput: "y"},
   981  		{name: "Clean install, no VPO is running", skipInstall: false, vpoExists: false},
   982  	}
   983  	for _, tt := range tests {
   984  		t.Run(tt.name, func(t *testing.T) {
   985  			c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateTestVPOObjects()...).Build()
   986  			cmd, _, _, _ := createNewTestCommandAndBuffers(t, c)
   987  			cmd.PersistentFlags().Set(constants.WaitFlag, "false")
   988  			if tt.skipInstall {
   989  				cmd.PersistentFlags().Set(constants.SkipPlatformOperatorFlag, "true")
   990  			}
   991  
   992  			if tt.cmdLineInput != "" {
   993  				content := []byte(tt.cmdLineInput)
   994  				tempfile, err := os.CreateTemp("", "test-input.txt")
   995  				if err != nil {
   996  					assert.Error(t, err)
   997  				}
   998  				// clean up tempfile
   999  				defer os.Remove(tempfile.Name())
  1000  				if _, err := tempfile.Write(content); err != nil {
  1001  					assert.Error(t, err)
  1002  				}
  1003  				if _, err := tempfile.Seek(0, 0); err != nil {
  1004  					assert.Error(t, err)
  1005  				}
  1006  				oldStdin := os.Stdin
  1007  				// Restore original Stdin
  1008  				defer func() { os.Stdin = oldStdin }()
  1009  				os.Stdin = tempfile
  1010  			}
  1011  
  1012  			cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc)
  1013  			defer cmdHelpers.SetDefaultDeleteFunc()
  1014  
  1015  			cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil })
  1016  			defer cmdHelpers.SetDefaultVPOIsReadyFunc()
  1017  
  1018  			SetValidateCRFunc(FakeValidateCRFunc)
  1019  			defer SetDefaultValidateCRFunc()
  1020  
  1021  			// Run install command
  1022  			err := cmd.Execute()
  1023  
  1024  			if tt.vpoExists {
  1025  				existingVPOPodList, _ := validators.GetPlatformOperatorPodList(c)
  1026  				assert.NotNil(t, existingVPOPodList)
  1027  				assert.Greater(t, len(existingVPOPodList.Items), 0)
  1028  			}
  1029  			assert.NoError(t, err)
  1030  			vz := v1alpha1.Verrazzano{}
  1031  			err = c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "verrazzano"}, &vz)
  1032  			assert.NoError(t, err)
  1033  
  1034  			expectedLastAppliedConfigAnnotation := "{\"apiVersion\":\"install.verrazzano.io/v1alpha1\",\"kind\":\"Verrazzano\",\"metadata\":{\"annotations\":{},\"name\":\"verrazzano\",\"namespace\":\"default\"}}\n"
  1035  			testhelpers.VerifyLastAppliedConfigAnnotation(t, vz.ObjectMeta, expectedLastAppliedConfigAnnotation)
  1036  		})
  1037  	}
  1038  }