diff --git a/components/automate-cli/cmd/chef-automate/upgrade.go b/components/automate-cli/cmd/chef-automate/upgrade.go index fa10b61efe5..958a8528691 100644 --- a/components/automate-cli/cmd/chef-automate/upgrade.go +++ b/components/automate-cli/cmd/chef-automate/upgrade.go @@ -24,6 +24,7 @@ import ( "github.com/chef/automate/components/automate-deployment/pkg/cli" "github.com/chef/automate/components/automate-deployment/pkg/client" "github.com/chef/automate/components/automate-deployment/pkg/inspector/upgradeinspectorv4" + "github.com/chef/automate/components/automate-deployment/pkg/inspector/upgradeinspectorv5" "github.com/chef/automate/components/automate-deployment/pkg/majorupgradechecklist" "github.com/chef/automate/components/automate-deployment/pkg/manifest" "github.com/chef/automate/components/automate-deployment/pkg/toml" @@ -224,6 +225,12 @@ func runUpgradeCmd(cmd *cobra.Command, args []string) error { if isError { return nil } + case "5": + upgradeInspector := upgradeinspectorv5.NewUpgradeInspectorV5(writer, upgradeinspectorv5.NewUpgradeV5Utils(), &fileutils.FileSystemUtils{}, configCmdFlags.timeout) + isError := upgradeInspector.RunUpgradeInspector(upgradeRunCmdFlags.osDestDataDir, upgradeRunCmdFlags.skipStorageCheck) + if isError { + return nil + } default: return status.Errorf(status.UpgradeError, "invalid major version") } diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/disablesharding.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/disablesharding.go new file mode 100644 index 00000000000..1d024c430b3 --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/disablesharding.go @@ -0,0 +1,91 @@ +package upgradeinspectorv5 + +import ( + "fmt" + "strings" + + "github.com/chef/automate/components/automate-deployment/pkg/cli" + "github.com/chef/automate/components/automate-deployment/pkg/inspector" + "github.com/fatih/color" + "github.com/pkg/errors" +) + +const ( + OS_URL = "http://localhost:10144/_cluster/settings" +) + +type DisableShardingInspection struct { + writer *cli.Writer + upgradeUtils UpgradeV5Utils + isExecuted bool + exitError error + exitedWithError bool +} + +func NewDisableShardingInspection(w *cli.Writer, utls UpgradeV5Utils) *DisableShardingInspection { + return &DisableShardingInspection{ + writer: w, + upgradeUtils: utls, + } +} + +func (ds *DisableShardingInspection) ShowInfo(index *int) error { + return nil +} +func (ds *DisableShardingInspection) Skip() { +} +func (ds *DisableShardingInspection) GetShortInfo() []string { + return nil +} + +func (ds *DisableShardingInspection) Inspect() (err error) { + disableShardingPayload := strings.NewReader(`{ + "persistent": { + "cluster.routing.allocation.enable": "primaries" + } + }`) + _, err = ds.upgradeUtils.ExecRequest(OS_URL, "PUT", disableShardingPayload) + if err != nil { + err = errors.Wrap(err, "Failed to disable sharding") + ds.setExitError(err) + return err + } + ds.setExecuted() + return nil +} + +func (ds *DisableShardingInspection) setExitError(err error) { + ds.exitError = err + ds.exitedWithError = true +} + +func (ds *DisableShardingInspection) setExecuted() { + ds.isExecuted = true +} + +func (ds *DisableShardingInspection) RollBackHandler() (err error) { + if !ds.isExecuted { + return nil + } + enableShardingPayload := strings.NewReader(`{ + "persistent": { + "cluster.routing.allocation.enable": null + } + }`) + _, err = ds.upgradeUtils.ExecRequest(OS_URL, "PUT", enableShardingPayload) + if err != nil { + return errors.Wrap(err, "Failed to enable sharding") + } + return nil +} + +func (ds *DisableShardingInspection) GetInstallationType() inspector.InstallationType { + return inspector.EMBEDDED +} + +func (ds *DisableShardingInspection) ExitHandler() error { + if ds.exitedWithError { + ds.writer.Println(fmt.Errorf("["+color.New(color.FgRed).Sprint("Error")+"] %w", ds.exitError).Error()) + } + return nil +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/disablesharding_test.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/disablesharding_test.go new file mode 100644 index 00000000000..217b88747e1 --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/disablesharding_test.go @@ -0,0 +1,47 @@ +package upgradeinspectorv5 + +import ( + "errors" + "io" + "testing" + + "github.com/chef/automate/lib/majorupgrade_utils" + "github.com/stretchr/testify/assert" +) + +func TestDisableSharding(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + ds := NewDisableShardingInspection(tw.CliWriter, &MockUpgradeV5UtilsImp{ + ExecRequestFunc: func(url, methodType string, requestBody io.Reader) ([]byte, error) { + return []byte{}, nil + }, + }) + err := ds.Inspect() + assert.NoError(t, err) +} + +func TestDisableShardingError(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + ds := NewDisableShardingInspection(tw.CliWriter, &MockUpgradeV5UtilsImp{ + ExecRequestFunc: func(url, methodType string, requestBody io.Reader) ([]byte, error) { + return nil, errors.New("Unreachable") + }, + }) + err := ds.Inspect() + assert.Error(t, err) +} + +func TestDisableShardingErrorExitHandlerMessage(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + ds := NewDisableShardingInspection(tw.CliWriter, &MockUpgradeV5UtilsImp{ + ExecRequestFunc: func(url, methodType string, requestBody io.Reader) ([]byte, error) { + return nil, errors.New("Unreachable") + }, + }) + err := ds.Inspect() + assert.Error(t, err) + err = ds.ExitHandler() + assert.NoError(t, err) + expected := `[Error] Failed to disable sharding: Unreachable` + assert.Contains(t, tw.Output(), expected) +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/diskspace.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/diskspace.go new file mode 100644 index 00000000000..ed555f32cdf --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/diskspace.go @@ -0,0 +1,325 @@ +package upgradeinspectorv5 + +import ( + "errors" + "fmt" + "time" + + "github.com/briandowns/spinner" + "github.com/chef/automate/components/automate-cli/pkg/status" + "github.com/chef/automate/components/automate-deployment/pkg/cli" + "github.com/chef/automate/components/automate-deployment/pkg/inspector" + "github.com/chef/automate/lib/io/fileutils" + "github.com/fatih/color" +) + +const ( + MIN_HAB_FREE_SPACE float64 = 5.5 + MIN_REQ_SPACE_STR = "The %s directory should have at least %.1fGB of free space" + ENSURE_SPACE = "\nPlease ensure the available free space is %.1fGB\nand run " + UPGRADE_CMD = "chef-automate upgrade run --major" + OS_DATA = "/svc/automate-opensearch/data" + PG_DATA = "/svc/automate-postgresql/data/pgdata13" +) + +type DiskSpaceInspection struct { + writer *cli.Writer + isExternalOS bool + isExternalPG bool + osDestDir string + pgDestDir string + fileutils fileutils.FileUtils + requiredHabSpace float64 + requiredOSDestSpace float64 + requiredPGDestSpace float64 + currentHabSpace float64 + currentSpaceInOSDir float64 + currentSpaceInPGDir float64 + habDir string + spinnerHab *spinner.Spinner + spinnerOSDestDir *spinner.Spinner + spinnerPGDestDir *spinner.Spinner + checkDelay time.Duration + exitError error + exitedWithError bool +} + +func (ds *DiskSpaceInspection) ShowInfo(index *int) (err error) { + ds.habDir = ds.fileutils.GetHabRootPath() + ds.currentHabSpace, err = ds.fileutils.GetFreeSpaceinGB(ds.habDir) + if err != nil { + return err + } + var osDataSize, pgDataSize float64 + ds.requiredHabSpace, osDataSize, pgDataSize, err = ds.GetSpaceNeeded(ds.habDir) + if err != nil { + return err + } + res, err := ds.writer.Confirm(fmt.Sprintf("%d. "+MIN_REQ_SPACE_STR+". (You have current available space : %.1fGB)", + *index, ds.habDir, ds.requiredHabSpace, ds.currentHabSpace)) + if err != nil { + ds.writer.Error(err.Error()) + return status.Errorf(status.InvalidCommandArgsError, err.Error()) + } + if !res { + ds.writer.Error(fmt.Sprintf(diskSpaceError, ds.requiredHabSpace)) + return status.New(status.InvalidCommandArgsError, fmt.Sprintf(diskSpaceError, ds.requiredHabSpace)) + } + *index++ + if !ds.isExternalOS && ds.hasOSDestDir() { + ds.requiredOSDestSpace = osDataSize + ds.currentSpaceInOSDir, err = ds.fileutils.GetFreeSpaceinGB(ds.osDestDir) + if err != nil { + return err + } + res, err := ds.writer.Confirm(fmt.Sprintf("%d. "+MIN_REQ_SPACE_STR+". (You have current available space : %.1fGB)", + *index, ds.osDestDir, ds.requiredOSDestSpace, ds.currentSpaceInOSDir)) + if err != nil { + ds.writer.Error(err.Error()) + return status.Errorf(status.InvalidCommandArgsError, err.Error()) + } + if !res { + ds.writer.Error(fmt.Sprintf(diskSpaceError, ds.requiredOSDestSpace)) + return status.New(status.InvalidCommandArgsError, fmt.Sprintf(diskSpaceError, ds.requiredOSDestSpace)) + } + *index++ + } + if !ds.isExternalPG { + ds.requiredPGDestSpace = pgDataSize + ds.currentSpaceInPGDir, err = ds.fileutils.GetFreeSpaceinGB(ds.pgDestDir) + if err != nil { + return err + } + res, err := ds.writer.Confirm(fmt.Sprintf("%d. "+MIN_REQ_SPACE_STR+". (You have current available space : %.1fGB)", + *index, ds.pgDestDir, ds.requiredPGDestSpace, ds.currentSpaceInPGDir)) + if err != nil { + ds.writer.Error(err.Error()) + return status.Errorf(status.InvalidCommandArgsError, err.Error()) + } + if !res { + ds.writer.Error(fmt.Sprintf(diskSpaceError, ds.requiredPGDestSpace)) + return status.New(status.InvalidCommandArgsError, fmt.Sprintf(diskSpaceError, ds.requiredPGDestSpace)) + } + *index++ + } + return nil +} + +func (ds *DiskSpaceInspection) hasOSDestDir() bool { + if ds.osDestDir != "" && ds.osDestDir != HAB_DIR { + return true + } + return false +} + +func NewDiskSpaceInspection(w *cli.Writer, isExternalOS bool, isExternalPG bool, osDestDir string, fileUtils fileutils.FileUtils) *DiskSpaceInspection { + return &DiskSpaceInspection{ + writer: w, + isExternalOS: isExternalOS, + isExternalPG: isExternalPG, + osDestDir: osDestDir, + pgDestDir: fileutils.GetHabRootPath() + PG_DATA, + fileutils: fileUtils, + checkDelay: 1000 * time.Millisecond, + } +} + +func (ds *DiskSpaceInspection) GetSpaceNeeded(habRootPath string) (habFreeSpace float64, osDataSize float64, pgDataSize float64, err error) { + if ds.isExternalOS && ds.isExternalPG { + return MIN_HAB_FREE_SPACE, -1, -1, nil + } else if ds.isExternalOS && !ds.isExternalPG { + pgDataPath := habRootPath + PG_DATA + var rawPGDataSize float64 + rawPGDataSize, err = ds.fileutils.CalDirSizeInGB(pgDataPath) + if err != nil { + return -1, -1, -1, err + } + habFreeSpace = MIN_HAB_FREE_SPACE + (rawPGDataSize * 110 / 100) + pgDataSize = (rawPGDataSize * 110 / 100) + osDataSize = -1 + if ds.hasOSDestDir() { + return MIN_HAB_FREE_SPACE, -1, pgDataSize, nil + } + } else if !ds.isExternalOS && ds.isExternalPG { + osDataPath := habRootPath + OS_DATA + var rawOSDataSize float64 + rawOSDataSize, err = ds.fileutils.CalDirSizeInGB(osDataPath) + if err != nil { + return -1, -1, -1, err + } + habFreeSpace = MIN_HAB_FREE_SPACE + (rawOSDataSize * 110 / 100) + osDataSize = (rawOSDataSize * 110 / 100) + pgDataSize = -1 + if ds.hasOSDestDir() { + return MIN_HAB_FREE_SPACE, osDataSize, -1, nil + } + } else { + pgDataPath := habRootPath + PG_DATA + var rawPGDataSize float64 + rawPGDataSize, err = ds.fileutils.CalDirSizeInGB(pgDataPath) + if err != nil { + return -1, -1, -1, err + } + pgDataSize = (rawPGDataSize * 110 / 100) + osDataPath := habRootPath + OS_DATA + var rawOSDataSize float64 + rawOSDataSize, err = ds.fileutils.CalDirSizeInGB(osDataPath) + if err != nil { + return -1, -1, -1, err + } + habFreeSpace = MIN_HAB_FREE_SPACE + (rawOSDataSize * 110 / 100) + (rawPGDataSize * 110 / 100) + osDataSize = (rawOSDataSize * 110 / 100) + if ds.hasOSDestDir() { + return MIN_HAB_FREE_SPACE, osDataSize, pgDataSize, nil + } + } + return +} + +func (ds *DiskSpaceInspection) showCheckingHab() { + ds.spinnerHab = ds.writer.NewSpinner() + ds.spinnerHab.Suffix = fmt.Sprintf(" [Checking]\t"+MIN_REQ_SPACE_STR, ds.habDir, ds.requiredHabSpace) + ds.spinnerHab.Start() + time.Sleep(ds.checkDelay) +} + +func (ds *DiskSpaceInspection) showCheckingPGDest() { + ds.spinnerPGDestDir = ds.writer.NewSpinner() + ds.spinnerPGDestDir.Suffix = fmt.Sprintf(" [Checking]\t"+MIN_REQ_SPACE_STR, ds.pgDestDir, ds.requiredPGDestSpace) + ds.spinnerPGDestDir.Start() + time.Sleep(ds.checkDelay) +} + +func (ds *DiskSpaceInspection) showCheckingOSDest() { + if ds.hasOSDestDir() { + ds.spinnerOSDestDir = ds.writer.NewSpinner() + ds.spinnerOSDestDir.Suffix = fmt.Sprintf(" [Checking]\t"+MIN_REQ_SPACE_STR, ds.osDestDir, ds.requiredOSDestSpace) + ds.spinnerOSDestDir.Start() + time.Sleep(ds.checkDelay) + } +} + +func (ds *DiskSpaceInspection) checkHabSpace() bool { + ds.showCheckingHab() + if ds.currentHabSpace > ds.requiredHabSpace { + ds.spinnerHab.FinalMSG = fmt.Sprintf(color.New(color.FgGreen).Sprint("✔")+" ["+color.New(color.FgGreen).Sprint("Passed")+ + "]\t"+MIN_REQ_SPACE_STR+"\n", ds.habDir, ds.requiredHabSpace) + ds.spinnerHab.Stop() + return true + } else { + ds.spinnerHab.FinalMSG = fmt.Sprintf(color.New(color.FgRed).Sprint("✖")+" ["+color.New(color.FgRed).Sprint("Failed")+ + "]\t"+MIN_REQ_SPACE_STR+"\n", ds.habDir, ds.requiredHabSpace) + ds.spinnerHab.Stop() + ds.skipOSDestCheck() + return false + } +} + +func (ds *DiskSpaceInspection) checkPGDestSpace() bool { + ds.showCheckingPGDest() + if ds.currentSpaceInPGDir > ds.requiredPGDestSpace { + ds.spinnerPGDestDir.FinalMSG = fmt.Sprintf(color.New(color.FgGreen).Sprint("✔")+" ["+color.New(color.FgGreen).Sprint("Passed")+ + "]\t"+MIN_REQ_SPACE_STR+"\n", ds.pgDestDir, ds.requiredPGDestSpace) + ds.spinnerPGDestDir.Stop() + return true + } else { + ds.spinnerPGDestDir.FinalMSG = fmt.Sprintf(color.New(color.FgRed).Sprint("✖")+" ["+color.New(color.FgRed).Sprint("Failed")+ + "]\t"+MIN_REQ_SPACE_STR+"\n", ds.pgDestDir, ds.requiredPGDestSpace) + ds.spinnerPGDestDir.Stop() + return false + } +} + +func (ds *DiskSpaceInspection) setErrHabSpace() { + errStr := "[" + color.New(color.FgRed).Sprint("Error") + fmt.Sprintf("] Required Space : %.1fGB\n", ds.requiredHabSpace) + errStr += fmt.Sprintf(" Available space : %.1fGB\n", ds.currentHabSpace) + errStr += fmt.Sprintf(ENSURE_SPACE+color.New(color.Bold).Sprint(UPGRADE_CMD)+" command again", ds.requiredHabSpace) + ds.exitError = errors.New(errStr) + ds.exitedWithError = true +} + +func (ds *DiskSpaceInspection) checkOSDestSpace() bool { + ds.showCheckingOSDest() + if ds.currentSpaceInOSDir > ds.requiredOSDestSpace { + ds.spinnerOSDestDir.FinalMSG = fmt.Sprintf(color.New(color.FgGreen).Sprint("✔")+" ["+color.New(color.FgGreen).Sprint("Passed")+ + "]\t"+MIN_REQ_SPACE_STR+"\n", ds.osDestDir, ds.requiredOSDestSpace) + ds.spinnerOSDestDir.Stop() + return true + } else { + ds.spinnerOSDestDir.FinalMSG = fmt.Sprintf(color.New(color.FgRed).Sprint("✖")+" ["+color.New(color.FgRed).Sprint("Failed")+ + "]\t"+MIN_REQ_SPACE_STR+"\n", ds.osDestDir, ds.requiredOSDestSpace) + ds.spinnerOSDestDir.Stop() + return false + } +} + +func (ds *DiskSpaceInspection) setOSDestError() { + errStr := "[" + color.New(color.FgRed).Sprint("Error") + fmt.Sprintf("] Required Space : %.1fGB\n", ds.requiredOSDestSpace) + errStr += fmt.Sprintf(" Available space : %.1fGB\n", ds.currentSpaceInOSDir) + errStr += fmt.Sprintf(ENSURE_SPACE+color.New(color.Bold).Sprint(UPGRADE_CMD)+" command again", ds.requiredOSDestSpace) + ds.exitError = errors.New(errStr) + ds.exitedWithError = true +} + +func (ds *DiskSpaceInspection) setPGDestError() { + errStr := "[" + color.New(color.FgRed).Sprint("Error") + fmt.Sprintf("] Required Space : %.1fGB\n", ds.requiredPGDestSpace) + errStr += fmt.Sprintf(" Available space : %.1fGB\n", ds.currentSpaceInPGDir) + errStr += fmt.Sprintf(ENSURE_SPACE+color.New(color.Bold).Sprint(UPGRADE_CMD)+" command again", ds.requiredPGDestSpace) + ds.exitError = errors.New(errStr) + ds.exitedWithError = true +} + +func (ds *DiskSpaceInspection) skipOSDestCheck() { + if ds.hasOSDestDir() { + ds.writer.Printf(" ⊖ [Skipped]\t"+MIN_REQ_SPACE_STR+"\n", ds.osDestDir, ds.requiredOSDestSpace) + } +} + +func (ds *DiskSpaceInspection) Skip() { + ds.writer.Printf(" ⊖ [Skipped]\t"+MIN_REQ_SPACE_STR+"\n", ds.habDir, ds.requiredHabSpace) + ds.skipOSDestCheck() +} + +func (ds *DiskSpaceInspection) Inspect() error { + isHabFree := ds.checkHabSpace() + if !isHabFree { + ds.setErrHabSpace() + return errors.New("failed in Hab Space Check") + } + if !ds.isExternalOS && ds.hasOSDestDir() { + isOSDestFree := ds.checkOSDestSpace() + if !isOSDestFree { + ds.setOSDestError() + return errors.New("failed in OS Dest Check") + } + } + if !ds.isExternalPG { + isPGDestFree := ds.checkPGDestSpace() + if !isPGDestFree { + ds.setPGDestError() + return errors.New("failed in PG Dest Check") + } + } + return nil +} + +func (ds *DiskSpaceInspection) GetShortInfo() []string { + msgs := []string{ + fmt.Sprintf(MIN_REQ_SPACE_STR, ds.habDir, ds.requiredHabSpace), + } + if ds.hasOSDestDir() { + msgs = append(msgs, fmt.Sprintf(MIN_REQ_SPACE_STR, ds.osDestDir, ds.requiredOSDestSpace)) + } + return msgs +} + +func (ds *DiskSpaceInspection) GetInstallationType() inspector.InstallationType { + return inspector.BOTH +} + +func (ds *DiskSpaceInspection) ExitHandler() error { + if ds.exitedWithError { + ds.writer.Println(ds.exitError.Error()) + } + return nil +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/diskspace_test.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/diskspace_test.go new file mode 100644 index 00000000000..80f9605ce28 --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/diskspace_test.go @@ -0,0 +1,239 @@ +package upgradeinspectorv5 + +import ( + "errors" + "testing" + "time" + + "github.com/chef/automate/lib/io/fileutils" + "github.com/chef/automate/lib/majorupgrade_utils" + "github.com/stretchr/testify/assert" +) + +func CalDirSizeInGB(path string) (float64, error) { + return 3.0, nil +} + +func CalDirSizeInGBError(path string) (float64, error) { + return 3.0, errors.New("failed to check filesystem") +} + +func GetFreeSpaceinGB(dir string) (float64, error) { + return 2.5, nil +} + +func GetFreeSpaceinGBToPassTest(dir string) (float64, error) { + return 12.5, nil +} + +func GetFreeSpaceinGBErrorHab(dir string) (float64, error) { + if dir == "/hab" { + return -1.0, errors.New("failed to check filesystem") + } + return 2.5, nil +} + +func GetFreeSpaceinGBErrorOSDestDir(dir string) (float64, error) { + if dir != "/hab" { + return -1.0, errors.New("failed to check filesystem") + } + return 2.5, nil +} +func GetHabRootPath() string { + return "/hab" +} + +func TestDiskSpaceInspection(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + mfs := &fileutils.MockFileSystemUtils{ + CalDirSizeInGBFunc: CalDirSizeInGB, + GetFreeSpaceinGBFunc: GetFreeSpaceinGB, + GetHabRootPathFunc: GetHabRootPath, + } + tb := NewDiskSpaceInspection(tw.CliWriter, false, false, "", mfs) + index := 3 + tb.ShowInfo(&index) + expected := "3. The /hab directory should have at least 8.8GB of free space. (You have current available space : 2.5GB) (y/n)\n" + + assert.Equal(t, expected, tw.Output()) + assert.Equal(t, 4, index) +} + +func TestDiskSpaceInspectionWithExternalOS(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + mfs := &fileutils.MockFileSystemUtils{ + CalDirSizeInGBFunc: CalDirSizeInGB, + GetFreeSpaceinGBFunc: GetFreeSpaceinGB, + GetHabRootPathFunc: GetHabRootPath, + } + tb := NewDiskSpaceInspection(tw.CliWriter, true, false, "", mfs) + index := 3 + tb.ShowInfo(&index) + expected := "3. The /hab directory should have at least 5.5GB of free space. (You have current available space : 2.5GB)\n (y/n)\n" + assert.Equal(t, expected, tw.Output()) + assert.Equal(t, 4, index) +} + +func TestDiskSpaceInspectionWithExternalPG(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + mfs := &fileutils.MockFileSystemUtils{ + CalDirSizeInGBFunc: CalDirSizeInGB, + GetFreeSpaceinGBFunc: GetFreeSpaceinGB, + GetHabRootPathFunc: GetHabRootPath, + } + tb := NewDiskSpaceInspection(tw.CliWriter, false, true, "", mfs) + index := 3 + tb.ShowInfo(&index) + expected := `3. The /hab directory should have at least 5.5GB of free space. (You have current available space : 2.5GB) +` + assert.Equal(t, expected, tw.Output()) + assert.Equal(t, 4, index) +} + +func TestDiskSpaceInspectionWithOSDataDir(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + mfs := &fileutils.MockFileSystemUtils{ + CalDirSizeInGBFunc: CalDirSizeInGB, + GetFreeSpaceinGBFunc: GetFreeSpaceinGB, + GetHabRootPathFunc: GetHabRootPath, + } + tb := NewDiskSpaceInspection(tw.CliWriter, false, false, "/home/ubuntu", mfs) + index := 3 + tb.ShowInfo(&index) + expected := `3. The /hab directory should have at least 5.5GB of free space. (You have current available space : 2.5GB) +4. The /home/ubuntu directory should have at least 3.3GB of free space. (You have current available space : 2.5GB) +` + assert.Equal(t, expected, tw.Output()) + assert.Equal(t, 5, index) +} + +func TestDiskSpaceInspectionFileSystemError(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + mfs := &fileutils.MockFileSystemUtils{ + CalDirSizeInGBFunc: CalDirSizeInGBError, + GetFreeSpaceinGBFunc: GetFreeSpaceinGB, + GetHabRootPathFunc: GetHabRootPath, + } + tb := NewDiskSpaceInspection(tw.CliWriter, false, false, "/home/ubuntu", mfs) + index := 3 + err := tb.ShowInfo(&index) + expected := "" + assert.Equal(t, expected, tw.Output()) + assert.Equal(t, 3, index) + if assert.Error(t, err) { + assert.Equal(t, "failed to check filesystem", err.Error()) + } +} + +func TestDiskSpaceInspectionFreeDiskFilesystemError(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + mfs := &fileutils.MockFileSystemUtils{ + CalDirSizeInGBFunc: CalDirSizeInGBError, + GetFreeSpaceinGBFunc: GetFreeSpaceinGB, + GetHabRootPathFunc: GetHabRootPath, + } + tb := NewDiskSpaceInspection(tw.CliWriter, false, false, "/home/ubuntu", mfs) + index := 3 + err := tb.ShowInfo(&index) + expected := "" + assert.Equal(t, expected, tw.Output()) + assert.Equal(t, 3, index) + if assert.Error(t, err) { + assert.Equal(t, "failed to check filesystem", err.Error()) + } +} + +func TestDiskSpaceInspectionWithHabFilesystemError(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + mfs := &fileutils.MockFileSystemUtils{ + CalDirSizeInGBFunc: CalDirSizeInGB, + GetFreeSpaceinGBFunc: GetFreeSpaceinGBErrorHab, + GetHabRootPathFunc: GetHabRootPath, + } + tb := NewDiskSpaceInspection(tw.CliWriter, false, false, "/home/ubuntu", mfs) + index := 3 + err := tb.ShowInfo(&index) + expected := "" + assert.Equal(t, expected, tw.Output()) + assert.Equal(t, 3, index) + if assert.Error(t, err) { + assert.Equal(t, "failed to check filesystem", err.Error()) + } +} + +func TestDiskSpaceInspectionWithOSDataDirFilesystemError(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + mfs := &fileutils.MockFileSystemUtils{ + CalDirSizeInGBFunc: CalDirSizeInGB, + GetFreeSpaceinGBFunc: GetFreeSpaceinGBErrorOSDestDir, + GetHabRootPathFunc: GetHabRootPath, + } + tb := NewDiskSpaceInspection(tw.CliWriter, false, false, "/home/ubuntu", mfs) + index := 3 + tb.ShowInfo(&index) + expected := `3. The /hab directory should have at least 5.5GB of free space. (You have current available space : 2.5GB) +` + assert.Equal(t, expected, tw.Output()) + assert.Equal(t, 4, index) +} + +func TestDiskSpaceInspect(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + mfs := &fileutils.MockFileSystemUtils{ + CalDirSizeInGBFunc: CalDirSizeInGB, + GetFreeSpaceinGBFunc: GetFreeSpaceinGB, + GetHabRootPathFunc: GetHabRootPath, + } + tb := NewDiskSpaceInspection(tw.CliWriter, false, false, "/home/ubuntu", mfs) + tb.habDir = "/hab" + tb.osDestDir = "/home/ubuntu" + tb.currentHabSpace = 8.5 + tb.requiredHabSpace = 5.5 + tb.currentSpaceInOSDir = 8.5 + tb.requiredOSDestSpace = 5.5 + tb.checkDelay = 100 * time.Millisecond + err := tb.Inspect() + expectedBeginHabChecking := "┤ [Checking]\tThe /hab directory should have at least 5.5GB of free space" + expectedBeginOSDestChecking := "┤ [Checking]\tThe /home/ubuntu directory should have at least 5.5GB of free space" + + expectedPassHabChecking := "✔ [Passed]\tThe /hab directory should have at least 5.5GB of free space" + expectedPassOSDestChecking := "✔ [Passed]\tThe /home/ubuntu directory should have at least 5.5GB of free space" + assert.Contains(t, tw.Output(), expectedBeginHabChecking) + assert.Contains(t, tw.Output(), expectedBeginOSDestChecking) + assert.Contains(t, tw.Output(), expectedPassHabChecking) + assert.Contains(t, tw.Output(), expectedPassOSDestChecking) + assert.NoError(t, err) +} + +func TestDiskSpaceInspectHabFailed(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + mfs := &fileutils.MockFileSystemUtils{ + CalDirSizeInGBFunc: CalDirSizeInGB, + GetFreeSpaceinGBFunc: GetFreeSpaceinGBErrorHab, + GetHabRootPathFunc: GetHabRootPath, + } + tb := NewDiskSpaceInspection(tw.CliWriter, false, false, "/home/ubuntu", mfs) + tb.habDir = "/hab" + tb.osDestDir = "/home/ubuntu" + tb.currentHabSpace = 8.5 + tb.requiredHabSpace = 10.5 + tb.currentSpaceInOSDir = 8.5 + tb.requiredOSDestSpace = 5.5 + tb.checkDelay = 100 * time.Millisecond + err := tb.Inspect() + expectedBeginHabChecking := "┤ [Checking]\tThe /hab directory should have at least 10.5GB of free space" + + expectedResult := `✖ [Failed] The /hab directory should have at least 10.5GB of free space + ⊖ [Skipped] The /home/ubuntu directory should have at least 5.5GB of free space +` + // expectedEnsureMsg := ` + // Please ensure the available free space is 10.5GB + // and run chef-automate upgrade run --major command again + // ` + assert.Contains(t, tw.Output(), expectedBeginHabChecking) + assert.Contains(t, tw.Output(), expectedResult) + // assert.Contains(t, tw.Output(), expectedEnsureMsg) + if assert.Error(t, err) { + assert.Equal(t, "failed in Hab Space Check", err.Error()) + } +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/enablemaintenance.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/enablemaintenance.go new file mode 100644 index 00000000000..6f1694bcb22 --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/enablemaintenance.go @@ -0,0 +1,118 @@ +package upgradeinspectorv5 + +import ( + "fmt" + "time" + + "github.com/briandowns/spinner" + "github.com/chef/automate/components/automate-deployment/pkg/cli" + "github.com/chef/automate/components/automate-deployment/pkg/inspector" + "github.com/fatih/color" +) + +type EnableMaintenanceInspection struct { + writer *cli.Writer + upgradeUtils UpgradeV5Utils + timeout int64 + isExecuted bool + spinner *spinner.Spinner + exitError error + exitedWithError bool +} + +func NewEnableMaintenanceInspection(w *cli.Writer, utls UpgradeV5Utils, timeout int64) *EnableMaintenanceInspection { + return &EnableMaintenanceInspection{ + writer: w, + upgradeUtils: utls, + timeout: timeout, + } +} + +func (em *EnableMaintenanceInspection) ShowInfo(index *int) error { + return nil +} +func (em *EnableMaintenanceInspection) Skip() { +} +func (em *EnableMaintenanceInspection) GetShortInfo() []string { + return nil +} + +func (em *EnableMaintenanceInspection) Inspect() (err error) { + em.showTurningOn() + isMaintenanceOn, err := em.upgradeUtils.GetMaintenanceStatus(em.timeout) + if err != nil { + em.showError() + em.setExitError(err) + return err + } + if isMaintenanceOn { + em.showSuccess() + return nil + } + _, _, err = em.upgradeUtils.SetMaintenanceMode(em.timeout, true) + if err != nil { + em.showError() + em.setExitError(err) + return err + } + em.setExecuted() + em.showSuccess() + return nil +} + +func (em *EnableMaintenanceInspection) setExitError(err error) { + em.exitedWithError = true + em.exitError = err +} + +func (em *EnableMaintenanceInspection) showTurningOn() { + em.spinner = em.writer.NewSpinner() + em.spinner.Suffix = " Turning ON maintenance mode" + em.spinner.Start() + time.Sleep(time.Second) +} + +func (em *EnableMaintenanceInspection) showSuccess() { + em.spinner.FinalMSG = "\n " + fmt.Sprintf(color.New(color.FgGreen).Sprint("✔")+" Maintenance mode turned ON successfully\n") + em.spinner.Stop() + em.writer.Println("") +} + +func (em *EnableMaintenanceInspection) showError() { + em.spinner.FinalMSG = " " + color.New(color.FgRed).Sprint("✖") + " Failed to turn maintenance mode ON" + em.spinner.Stop() + em.writer.Println("") +} + +func (em *EnableMaintenanceInspection) setExecuted() { + em.isExecuted = true +} + +func (em *EnableMaintenanceInspection) RollBackHandler() (err error) { + if !em.isExecuted { + return nil + } + isMaintenanceOn, err := em.upgradeUtils.GetMaintenanceStatus(em.timeout) + if err != nil { + return err + } + if !isMaintenanceOn { + return nil + } + _, _, err = em.upgradeUtils.SetMaintenanceMode(em.timeout, false) + if err != nil { + return err + } + return nil +} + +func (em *EnableMaintenanceInspection) GetInstallationType() inspector.InstallationType { + return inspector.BOTH +} + +func (em *EnableMaintenanceInspection) ExitHandler() error { + if em.exitedWithError { + em.writer.Println(fmt.Errorf("["+color.New(color.FgRed).Sprint("Error")+"] %w", em.exitError).Error()) + } + return nil +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/enablemaintenance_test.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/enablemaintenance_test.go new file mode 100644 index 00000000000..de4fd015e05 --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/enablemaintenance_test.go @@ -0,0 +1,111 @@ +package upgradeinspectorv5 + +import ( + "errors" + "testing" + + "github.com/chef/automate/lib/majorupgrade_utils" + "github.com/stretchr/testify/assert" +) + +func TestInspectDisableMaintenanceAlreadyOn(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + dm := NewEnableMaintenanceInspection(tw.CliWriter, &MockUpgradeV5UtilsImp{ + GetMaintenanceStatusFunc: func(timeout int64) (bool, error) { + return true, nil + }, + SetMaintenanceModeFunc: func(timeout int64, status bool) (stdOut, stdErr string, err error) { + return "", "", nil + }, + }, 10) + err := dm.Inspect() + assert.NoError(t, err) +} + +func TestInspectDisableMaintenance(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + dm := NewEnableMaintenanceInspection(tw.CliWriter, &MockUpgradeV5UtilsImp{ + GetMaintenanceStatusFunc: func(timeout int64) (bool, error) { + return false, nil + }, + SetMaintenanceModeFunc: func(timeout int64, status bool) (stdOut, stdErr string, err error) { + return "", "", nil + }, + }, 10) + err := dm.Inspect() + assert.NoError(t, err) +} + +func TestInspectDisableMaintenanceError(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + dm := NewEnableMaintenanceInspection(tw.CliWriter, &MockUpgradeV5UtilsImp{ + GetMaintenanceStatusFunc: func(timeout int64) (bool, error) { + return false, nil + }, + SetMaintenanceModeFunc: func(timeout int64, status bool) (stdOut, stdErr string, err error) { + return "", "", errors.New("Unexpected") + }, + }, 10) + err := dm.Inspect() + assert.Error(t, err) +} + +func TestInspectDisableMaintenanceRollBackCalled(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + dm := NewEnableMaintenanceInspection(tw.CliWriter, &MockUpgradeV5UtilsImp{ + GetMaintenanceStatusFunc: func(timeout int64) (bool, error) { + return true, nil + }, + SetMaintenanceModeFunc: func(timeout int64, status bool) (stdOut, stdErr string, err error) { + return "", "", nil + }, + }, 10) + dm.isExecuted = true + err := dm.RollBackHandler() + assert.NoError(t, err) +} + +func TestInspectDisableMaintenanceRollBackCalledWithErrorGet(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + dm := NewEnableMaintenanceInspection(tw.CliWriter, &MockUpgradeV5UtilsImp{ + GetMaintenanceStatusFunc: func(timeout int64) (bool, error) { + return false, errors.New("unexpected") + }, + SetMaintenanceModeFunc: func(timeout int64, status bool) (stdOut, stdErr string, err error) { + return "", "", nil + }, + }, 10) + dm.isExecuted = true + err := dm.RollBackHandler() + assert.Error(t, err) +} + +func TestInspectDisableMaintenanceRollBackCalledWithErrorSet(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + dm := NewEnableMaintenanceInspection(tw.CliWriter, &MockUpgradeV5UtilsImp{ + GetMaintenanceStatusFunc: func(timeout int64) (bool, error) { + return true, nil + }, + SetMaintenanceModeFunc: func(timeout int64, status bool) (stdOut, stdErr string, err error) { + return "", "", errors.New("unexpected") + }, + }, 10) + dm.isExecuted = true + err := dm.RollBackHandler() + assert.Error(t, err) +} + +func TestInspectDisableMaintenanceRollBackCalledMaintenanceAlreadyOff(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + dm := NewEnableMaintenanceInspection(tw.CliWriter, &MockUpgradeV5UtilsImp{ + GetMaintenanceStatusFunc: func(timeout int64) (bool, error) { + return false, nil + }, + SetMaintenanceModeFunc: func(timeout int64, status bool) (stdOut, stdErr string, err error) { + return "", "", nil + }, + }, 10) + dm.isExecuted = true + err := dm.RollBackHandler() + assert.NoError(t, err) +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/ensureStatus.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/ensureStatus.go new file mode 100644 index 00000000000..2a49a372604 --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/ensureStatus.go @@ -0,0 +1,63 @@ +package upgradeinspectorv5 + +import ( + "errors" + "fmt" + + "github.com/chef/automate/components/automate-deployment/pkg/cli" + "github.com/chef/automate/components/automate-deployment/pkg/inspector" + "github.com/fatih/color" +) + +type EnsureStatusInspection struct { + writer *cli.Writer + upgradeUtils UpgradeV5Utils + exitError error + exitedWithError bool +} + +func NewEnsureStatusInspection(w *cli.Writer, upgradeUtils UpgradeV5Utils) *EnsureStatusInspection { + return &EnsureStatusInspection{ + writer: w, + upgradeUtils: upgradeUtils, + } +} + +func (es *EnsureStatusInspection) ShowInfo(index *int) error { + return nil +} +func (es *EnsureStatusInspection) Skip() {} + +func (es *EnsureStatusInspection) GetShortInfo() []string { + return nil +} + +func (es *EnsureStatusInspection) Inspect() (err error) { + status, err := es.upgradeUtils.GetServicesStatus() + if err != nil { + es.setExitError(err) + return err + } + if !status { + err = errors.New("Please make sure all services are healthy by running " + color.New(color.Bold).Sprint("chef-automate status")) + es.setExitError(err) + return err + } + return nil +} + +func (es *EnsureStatusInspection) setExitError(err error) { + es.exitError = err + es.exitedWithError = true +} + +func (es *EnsureStatusInspection) GetInstallationType() inspector.InstallationType { + return inspector.BOTH +} + +func (es *EnsureStatusInspection) ExitHandler() error { + if es.exitedWithError { + es.writer.Println(fmt.Errorf("["+color.New(color.FgRed).Sprint("Error")+"] %w", es.exitError).Error()) + } + return nil +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/ensureStatus_test.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/ensureStatus_test.go new file mode 100644 index 00000000000..19cc14b31d8 --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/ensureStatus_test.go @@ -0,0 +1,38 @@ +package upgradeinspectorv5 + +import ( + "errors" + "testing" + + "github.com/chef/automate/lib/majorupgrade_utils" + "github.com/stretchr/testify/assert" +) + +func TestInspectEnsureStatus(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + ds := NewEnsureStatusInspection(tw.CliWriter, &MockUpgradeV5UtilsImp{ + GetServicesStatusFunc: func() (bool, error) { + return false, nil + }, + }) + err := ds.Inspect() + expected := "Please make sure all services are healthy by running chef-automate status" + assert.Error(t, err) + assert.Equal(t, expected, err.Error()) +} + +func TestInspectEnsureStatusError(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + ds := NewEnsureStatusInspection(tw.CliWriter, &MockUpgradeV5UtilsImp{ + GetServicesStatusFunc: func() (bool, error) { + return false, errors.New("unexpected") + }, + }) + err := ds.Inspect() + assert.Error(t, err) + err = ds.ExitHandler() + assert.NoError(t, err) + expected := "[Error] unexpected\n" + assert.Equal(t, expected, tw.Output()) + +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/externalpgupgradecheck.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/externalpgupgradecheck.go new file mode 100644 index 00000000000..1217cd5a77c --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/externalpgupgradecheck.go @@ -0,0 +1,36 @@ +package upgradeinspectorv5 + +import ( + "fmt" + + "github.com/chef/automate/components/automate-cli/pkg/status" + "github.com/chef/automate/components/automate-deployment/pkg/cli" +) + +type ExternalPGUpgradeCheckInspection struct { + writer *cli.Writer + isExternalPG bool +} + +func (pd *ExternalPGUpgradeCheckInspection) ShowInfo(index *int) error { + if pd.isExternalPG { + res, err := pd.writer.Confirm(fmt.Sprintf("%d. Upgrade your PostgreSQL 13.5 to 17.0 with the help of your Database Administrator", *index)) + if err != nil { + pd.writer.Error(err.Error()) + return status.Errorf(status.InvalidCommandArgsError, err.Error()) + } + if !res { + pd.writer.Error(backupError) + return status.New(status.InvalidCommandArgsError, downTimeError) + } + *index++ + } + return nil +} + +func NewExternalPGUpgradeCheckInspection(w *cli.Writer, isExternalPG bool) *ExternalPGUpgradeCheckInspection { + return &ExternalPGUpgradeCheckInspection{ + writer: w, + isExternalPG: isExternalPG, + } +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/externalpgupgradecheck_test.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/externalpgupgradecheck_test.go new file mode 100644 index 00000000000..5eaa2982ef1 --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/externalpgupgradecheck_test.go @@ -0,0 +1,17 @@ +package upgradeinspectorv5 + +import ( + "testing" + + "github.com/chef/automate/lib/majorupgrade_utils" + "github.com/stretchr/testify/assert" +) + +func TestExternalPGUpgradeCheck(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + ex := NewExternalPGUpgradeCheckInspection(tw.CliWriter, true) + index := 4 + ex.ShowInfo(&index) + expected := "4. Upgrade your PostgreSQL 13.5 to 17.0 with the help of your Database Administrator (y/n)\n" + assert.Equal(t, expected, tw.Output()) +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/plandowntime.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/plandowntime.go new file mode 100644 index 00000000000..881985e5f0f --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/plandowntime.go @@ -0,0 +1,32 @@ +package upgradeinspectorv5 + +import ( + "fmt" + + "github.com/chef/automate/components/automate-cli/pkg/status" + "github.com/chef/automate/components/automate-deployment/pkg/cli" +) + +type PlannedDownTimeInspection struct { + writer *cli.Writer +} + +func (pd *PlannedDownTimeInspection) ShowInfo(index *int) error { + res, err := pd.writer.Confirm(fmt.Sprintf("%d. You have scheduled downtime for the duration of the upgrade.", *index)) + if err != nil { + pd.writer.Error(err.Error()) + return status.Errorf(status.InvalidCommandArgsError, err.Error()) + } + if !res { + pd.writer.Error(downTimeError) + return status.New(status.InvalidCommandArgsError, downTimeError) + } + *index++ + return nil +} + +func NewPlannedDownTimeInspection(w *cli.Writer) *PlannedDownTimeInspection { + return &PlannedDownTimeInspection{ + writer: w, + } +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/plandowntime_test.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/plandowntime_test.go new file mode 100644 index 00000000000..1417aa073f4 --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/plandowntime_test.go @@ -0,0 +1,17 @@ +package upgradeinspectorv5 + +import ( + "testing" + + "github.com/chef/automate/lib/majorupgrade_utils" + "github.com/stretchr/testify/assert" +) + +func TestPlanDownTime(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + pd := NewPlannedDownTimeInspection(tw.CliWriter) + index := 1 + pd.ShowInfo(&index) + expected := "1. You have scheduled downtime for the duration of the upgrade. (y/n)\n" + assert.Equal(t, expected, tw.Output()) +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/postchecklistIntimation.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/postchecklistIntimation.go new file mode 100644 index 00000000000..4a12baa037a --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/postchecklistIntimation.go @@ -0,0 +1,32 @@ +package upgradeinspectorv5 + +import ( + "fmt" + + "github.com/chef/automate/components/automate-cli/pkg/status" + "github.com/chef/automate/components/automate-deployment/pkg/cli" +) + +type PostChecklistIntimationCheckInspection struct { + writer *cli.Writer +} + +func (pd *PostChecklistIntimationCheckInspection) ShowInfo(index *int) error { + res, err := pd.writer.Confirm(fmt.Sprintf("%d. After this upgrade completes, you will have to run Post upgrade steps to ensure your data is migrated and your Automate is ready for use", *index)) + if err != nil { + pd.writer.Error(err.Error()) + return status.Errorf(status.InvalidCommandArgsError, err.Error()) + } + if !res { + pd.writer.Error(postChecklistIntimationError) + return status.New(status.InvalidCommandArgsError, postChecklistIntimationError) + } + *index++ + return nil +} + +func NewPostChecklistIntimationCheckInspection(w *cli.Writer) *PostChecklistIntimationCheckInspection { + return &PostChecklistIntimationCheckInspection{ + writer: w, + } +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/postchecklistIntimation_test.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/postchecklistIntimation_test.go new file mode 100644 index 00000000000..f71d77b796f --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/postchecklistIntimation_test.go @@ -0,0 +1,17 @@ +package upgradeinspectorv5 + +import ( + "testing" + + "github.com/chef/automate/lib/majorupgrade_utils" + "github.com/stretchr/testify/assert" +) + +func TestPostChecklistIntimationCheck(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + pc := NewPostChecklistIntimationCheckInspection(tw.CliWriter) + index := 5 + pc.ShowInfo(&index) + expected := "5. After this upgrade completes, you will have to run Post upgrade steps to ensure your data is migrated and your Automate is ready for use (y/n)\n" + assert.Equal(t, expected, tw.Output()) +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/reindexing.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/reindexing.go new file mode 100644 index 00000000000..cbf7860a652 --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/reindexing.go @@ -0,0 +1,36 @@ +package upgradeinspectorv5 + +import ( + "fmt" + + "github.com/chef/automate/components/automate-cli/pkg/status" + "github.com/chef/automate/components/automate-deployment/pkg/cli" +) + +type ReindexingInspection struct { + writer *cli.Writer + isExternalOS bool +} + +func (ri *ReindexingInspection) ShowInfo(index *int) error { + if !ri.isExternalOS { + res, err := ri.writer.Confirm(fmt.Sprintf("%d. Have you done the reindexing?", *index)) + if err != nil { + ri.writer.Error(err.Error()) + return status.Errorf(status.InvalidCommandArgsError, err.Error()) + } + if !res { + ri.writer.Error(reindexingError) + return status.New(status.InvalidCommandArgsError, reindexingError) + } + *index++ + } + return nil +} + +func NewReindexingInspection(w *cli.Writer, isExternalOS bool) *ReindexingInspection { + return &ReindexingInspection{ + writer: w, + isExternalOS: isExternalOS, + } +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/reindexing_test.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/reindexing_test.go new file mode 100644 index 00000000000..e517dee018c --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/reindexing_test.go @@ -0,0 +1,17 @@ +package upgradeinspectorv5 + +import ( + "testing" + + "github.com/chef/automate/lib/majorupgrade_utils" + "github.com/stretchr/testify/assert" +) + +func TestReIndexing(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + ri := NewReindexingInspection(tw.CliWriter, false) + index := 1 + ri.ShowInfo(&index) + expected := "1. You want to do reindexing. (y/n)\n" + assert.Equal(t, expected, tw.Output()) +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/takebackup.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/takebackup.go new file mode 100644 index 00000000000..158b677818d --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/takebackup.go @@ -0,0 +1,34 @@ +package upgradeinspectorv5 + +import ( + "fmt" + + "github.com/chef/automate/components/automate-cli/pkg/status" + "github.com/chef/automate/components/automate-deployment/pkg/cli" + "github.com/fatih/color" +) + +type TakeBackupInspection struct { + writer *cli.Writer +} + +func (tb *TakeBackupInspection) ShowInfo(index *int) error { + res, err := tb.writer.Confirm(fmt.Sprintf("%d. You have taken a backup by running the command: "+ + color.New(color.Bold).Sprint("chef automate backup create")+".", *index)) + if err != nil { + tb.writer.Error(err.Error()) + return status.Errorf(status.InvalidCommandArgsError, err.Error()) + } + if !res { + tb.writer.Error(backupError) + return status.New(status.InvalidCommandArgsError, backupError) + } + *index++ + return nil +} + +func NewTakeBackupInspection(w *cli.Writer) *TakeBackupInspection { + return &TakeBackupInspection{ + writer: w, + } +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/takebackup_test.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/takebackup_test.go new file mode 100644 index 00000000000..4dff8b29dc2 --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/takebackup_test.go @@ -0,0 +1,17 @@ +package upgradeinspectorv5 + +import ( + "testing" + + "github.com/chef/automate/lib/majorupgrade_utils" + "github.com/stretchr/testify/assert" +) + +func TestTakeBackup(t *testing.T) { + tw := majorupgrade_utils.NewCustomWriter() + tb := NewTakeBackupInspection(tw.CliWriter) + index := 2 + tb.ShowInfo(&index) + expected := "2. You have taken a backup by running the command: chef automate backup create. (y/n)\n" + assert.Equal(t, expected, tw.Output()) +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/upgradeInspectorV5.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/upgradeInspectorV5.go new file mode 100644 index 00000000000..9dc21419254 --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/upgradeInspectorV5.go @@ -0,0 +1,254 @@ +package upgradeinspectorv5 + +import ( + "strings" + + "github.com/fatih/color" + "github.com/pkg/errors" + + "github.com/chef/automate/components/automate-deployment/pkg/cli" + "github.com/chef/automate/components/automate-deployment/pkg/inspector" + "github.com/chef/automate/lib/io/fileutils" +) + +type UpgradeInspectorV5 struct { + writer *cli.Writer + inspections []inspector.Inspection + osDestDir string + skipStorageCheck bool + upgradeUtils UpgradeV5Utils + fileUtils fileutils.FileUtils + timeout int64 + isExternalOS bool + isExternalPG bool +} + +const ( + HAB_DIR string = "/hab" + UPGRADE_TERMINATED string = "Upgrade process terminated." +) + +func (ui *UpgradeInspectorV5) ShowInfo() error { + ui.writer.Println(`This is a major upgrade! + In this Release +1) Embedded OpenSearch v4 will be upgraded to OpenSearch v5. +2) Embedded PostgreSQL v13.5 will be upgraded to version v17.0 +`) + if len(ui.inspections) > 0 { + ui.writer.Println("Before proceeding, please ensure:") + } + index := 1 + for _, inspection := range ui.inspections { + err := inspection.ShowInfo(&index) + if err != nil { + return err + } + } + if len(ui.inspections) > 0 { + ui.writer.Println("") + } + + if !ui.upgradeUtils.IsExternalOpenSearch(ui.timeout) && (len(ui.osDestDir) == 0 || ui.osDestDir == HAB_DIR) { + ui.showOSDestDirFlagMsg() + } + ui.writer.Println("For more information, visit") + ui.writer.Println(color.New(color.FgBlue).Sprint("https://docs.chef.io/automate/major_upgrade_5.x/\n")) + return ui.promptToContinue() +} + +func (ui *UpgradeInspectorV5) promptToContinue() error { + isContinue, err := ui.writer.Confirm("Would you like to proceed with the upgrade?") + if err != nil { + return err + } + if !isContinue { + return errors.New(UPGRADE_TERMINATED) + } + return nil +} + +func (ui *UpgradeInspectorV5) showOSDestDirFlagMsg() { + ui.writer.Println(`You can always change the OpenSearch destination directory by using the flag: + $ chef-automate upgrade run --major --os-dest-data-dir +`) +} + +func (ui *UpgradeInspectorV5) checkInstallationTypeForExternal(installationType inspector.InstallationType) bool { + return ui.isExternalOS && (installationType == inspector.EXTERNAL || installationType == inspector.BOTH) +} + +func (ui *UpgradeInspectorV5) checkInstallationTypeForEmbedded(installationType inspector.InstallationType) bool { + return !ui.isExternalOS && (installationType == inspector.EMBEDDED || installationType == inspector.BOTH) +} + +func (ui *UpgradeInspectorV5) Inspect() (err error) { + ui.writer.Println("Pre flight checks") + for _, inspection := range ui.inspections { + var i interface{} = inspection + _, ok := i.(inspector.SystemInspection) + if ok { + installationType := inspection.(inspector.SystemInspection).GetInstallationType() + if ui.checkInstallationTypeForExternal(installationType) || ui.checkInstallationTypeForEmbedded(installationType) { + if err != nil { + inspection.(inspector.SystemInspection).Skip() + } else { + err = inspection.(inspector.SystemInspection).Inspect() + } + } + } + } + if err != nil { + return err + } + return nil +} + +func (ui *UpgradeInspectorV5) RollBackChangesOnError() (err error) { + for _, inspection := range ui.inspections { + var i interface{} = inspection + _, ok := i.(inspector.RollbackInspection) + if ok { + err = inspection.(inspector.RollbackInspection).RollBackHandler() + if err != nil { + return err + } + } + } + return nil +} + +func NewUpgradeInspectorV5(w *cli.Writer, upgradeUtils UpgradeV5Utils, fileUtils fileutils.FileUtils, timeout int64) inspector.Inspector { + + return &UpgradeInspectorV5{ + writer: w, + upgradeUtils: upgradeUtils, + fileUtils: fileUtils, + timeout: timeout, + isExternalOS: upgradeUtils.IsExternalOpenSearch(timeout), + isExternalPG: upgradeUtils.IsExternalPG(), + } +} + +func (ui *UpgradeInspectorV5) SetOSDestDir(path string) { + if strings.TrimSpace(path) != "" { + ui.osDestDir = path + } +} + +func (ui *UpgradeInspectorV5) SetSkipStoragecheckFlag(check bool) { + ui.skipStorageCheck = check +} + +func (ui *UpgradeInspectorV5) AddInspection(inspection inspector.Inspection) { + if inspection != nil { + ui.inspections = append(ui.inspections, inspection) + } +} + +func (ui *UpgradeInspectorV5) AddDefaultInspections() { + ui.AddInspection(NewEnsureStatusInspection(ui.writer, ui.upgradeUtils)) + ui.AddInspection(NewPlannedDownTimeInspection(ui.writer)) + ui.AddInspection(NewTakeBackupInspection(ui.writer)) + if !ui.skipStorageCheck { + diskSpaceInspection := NewDiskSpaceInspection(ui.writer, ui.isExternalOS, ui.isExternalPG, ui.osDestDir, ui.fileUtils) + ui.AddInspection(diskSpaceInspection) + } + ui.AddInspection(NewExternalPGUpgradeCheckInspection(ui.writer, ui.isExternalPG)) + ui.AddInspection(NewReindexingInspection(ui.writer, ui.isExternalOS)) + ui.AddInspection(NewPostChecklistIntimationCheckInspection(ui.writer)) + ui.AddInspection(NewDisableShardingInspection(ui.writer, ui.upgradeUtils)) + ui.AddInspection(NewEnableMaintenanceInspection(ui.writer, ui.upgradeUtils, ui.timeout)) +} + +func (ui *UpgradeInspectorV5) ShowInspectionList() { + ui.writer.Println("\nFollowing Pre-flight checks will be conducted") + index := 1 + for _, inspection := range ui.inspections { + var i interface{} = inspection + _, ok := i.(inspector.SystemInspection) + if ok { + installationType := inspection.(inspector.SystemInspection).GetInstallationType() + if ui.checkInstallationTypeForExternal(installationType) || ui.checkInstallationTypeForEmbedded(installationType) { + msgs := inspection.(inspector.SystemInspection).GetShortInfo() + for _, msg := range msgs { + if msg != "" { + ui.writer.Printf("%d. %s\n", index, msg) + index++ + } + } + } + } + } + ui.writer.Println("") +} + +func (ui *UpgradeInspectorV5) RunExitAction() error { + for _, inspection := range ui.inspections { + var i interface{} = inspection + _, ok := i.(inspector.SystemInspection) + if ok { + err := inspection.(inspector.SystemInspection).ExitHandler() + if err != nil { + return err + } + } + } + return nil +} + +func (ui *UpgradeInspectorV5) handleError(errArray []error) { + if len(errArray) == 1 { + if errArray[0].Error() != UPGRADE_TERMINATED { + ui.writer.Println("[" + color.New(color.FgRed).Sprint("Error") + "] " + errArray[0].Error()) + ui.printContactSupport() + } + } else if len(errArray) > 1 { + ui.writer.Println("[" + color.New(color.FgRed).Sprint("Error") + "] " + errArray[len(errArray)-1].Error()) + for i := len(errArray) - 1; i >= 0; i-- { + if i == len(errArray)-1 { + ui.writer.Println("[" + color.New(color.FgRed).Sprint("Error") + "] " + errArray[i].Error()) + } else { + ui.writer.Println(errArray[i].Error()) + } + } + ui.printContactSupport() + } + +} + +func (ui *UpgradeInspectorV5) printContactSupport() { + ui.writer.Println("Please resolve this and try again.") + ui.writer.Println("Please contact support if you are not sure how to resolve this.") +} + +func (ui *UpgradeInspectorV5) RunUpgradeInspector(osDestDir string, skipStorageCheck bool) (isError bool) { + errArray := []error{} + ui.SetOSDestDir(osDestDir) + ui.SetSkipStoragecheckFlag(skipStorageCheck) + ui.AddDefaultInspections() + err := ui.ShowInfo() + if err != nil { + ui.handleError(append(errArray, err)) + ui.writer.Println(UPGRADE_TERMINATED) + return true + } + ui.ShowInspectionList() + err = ui.Inspect() + if err != nil { + ui.writer.Println("") + err = ui.RollBackChangesOnError() + if err != nil { + errArray = append(errArray, err) + } + err = ui.RunExitAction() + if err != nil { + errArray = append(errArray, err) + } + if len(errArray) > 0 { + ui.handleError(errArray) + } + ui.writer.Println(UPGRADE_TERMINATED) + return true + } + return false +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/upgradeInspectorV5_test.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/upgradeInspectorV5_test.go new file mode 100644 index 00000000000..fc9ae933f9c --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/upgradeInspectorV5_test.go @@ -0,0 +1,586 @@ +package upgradeinspectorv5 + +// import ( +// "errors" +// "fmt" +// "io" +// "strings" +// "testing" +// "time" + +// "github.com/chef/automate/lib/io/fileutils" +// "github.com/chef/automate/lib/majorupgrade_utils" +// "github.com/stretchr/testify/assert" +// ) + +// const ( +// TITLE_MSG = `This is a major upgrade! +// In this release, Elasticsearch will be migrated to OpenSearch.` +// RUN_WITH_OS_FLAG = `You can always change the OpenSearch destination directory by using the flag: +// $ chef-automate upgrade run --major --os-dest-data-dir ` +// PROCEED_CONF = `For more information, visit +// https://docs.chef.io/automate/major_upgrade_4.x/ + +// Would you like to proceed with the upgrade? (y/n)` +// INFO_MSG = `Before proceeding, please ensure: +// 1. You have scheduled downtime for the duration of the upgrade. +// 2. You have taken a backup by running the command: chef automate backup create. +// 3. The /hab directory should have at least 8.8GB of free space. (You have current available space : 2.5GB)` +// INSPECTION_LIST = `Following Pre-flight checks will be conducted +// 1. The /hab directory should have at least 5.5GB of free space +// 2. The /home/ubuntu directory should have at least 3.3GB of free space +// ` +// ALL_SKIPPED_OS = `Pre flight checks +// ⊖ [Skipped] The /hab directory should have at least 5.5GB of free space +// ⊖ [Skipped] The /home/ubuntu directory should have at least 3.3GB of free space +// ⊖ [Skipped] Elasticsearch indices are in version 6 + +// [Error] Please make sure all services are healthy by running chef-automate status` +// HAB_SPACE_ERR = `✖ [Failed] The /hab directory should have at least 8.8GB of free space +// ⊖ [Skipped] Elasticsearch indices are in version 6 + +// [Error] Required Space : 8.8GB +// Available space : 2.5GB + +// Please ensure the available free space is 8.8GB +// and run chef-automate upgrade run --major command again +// ` +// ) + +// func TestUpgradeInspectorV5ShowInfoWithNoInspections(t *testing.T) { +// tw := majorupgrade_utils.NewCustomWriterWithInputs("y") +// expected := fmt.Sprintf("%s\n\n%s\n\n%s\n", TITLE_MSG, RUN_WITH_OS_FLAG, PROCEED_CONF) +// mfs := &fileutils.MockFileSystemUtils{ +// CalDirSizeInGBFunc: CalDirSizeInGB, +// GetFreeSpaceinGBFunc: GetFreeSpaceinGB, +// GetHabRootPathFunc: GetHabRootPath, +// } +// ui := NewUpgradeInspectorV5(tw.CliWriter, &MockUpgradeV5UtilsImp{ +// IsExternalElasticSearchFunc: func(timeout int64) bool { return false }, +// }, mfs, 10) +// err := ui.ShowInfo() +// t.Log(tw.Output()) +// t.Log(expected) +// assert.Equal(t, expected, tw.Output()) +// assert.NoError(t, err) +// } + +// func TestUpgradeInspectorV5ShowInfoWithOSDestDirIsHab(t *testing.T) { +// tw := majorupgrade_utils.NewCustomWriterWithInputs("y") +// expected := fmt.Sprintf("%s\n\n%s\n\n%s\n", TITLE_MSG, RUN_WITH_OS_FLAG, PROCEED_CONF) +// mfs := &fileutils.MockFileSystemUtils{ +// CalDirSizeInGBFunc: CalDirSizeInGB, +// GetFreeSpaceinGBFunc: GetFreeSpaceinGB, +// GetHabRootPathFunc: GetHabRootPath, +// } +// ui := NewUpgradeInspectorV5(tw.CliWriter, &MockUpgradeV5UtilsImp{ +// IsExternalElasticSearchFunc: func(timeout int64) bool { return false }, +// }, mfs, 10) +// ui.(*UpgradeInspectorV5).SetOSDestDir("/hab") +// err := ui.ShowInfo() +// assert.Equal(t, expected, tw.Output()) +// assert.NoError(t, err) +// } + +// func TestUpgradeInspectorV5ShowInfoWithOSDestDir(t *testing.T) { +// tw := majorupgrade_utils.NewCustomWriterWithInputs("y") +// expected := fmt.Sprintf("%s\n\n%s\n", TITLE_MSG, PROCEED_CONF) +// mfs := &fileutils.MockFileSystemUtils{ +// CalDirSizeInGBFunc: CalDirSizeInGB, +// GetFreeSpaceinGBFunc: GetFreeSpaceinGB, +// GetHabRootPathFunc: GetHabRootPath, +// } +// ui := NewUpgradeInspectorV5(tw.CliWriter, &MockUpgradeV5UtilsImp{ +// IsExternalElasticSearchFunc: func(timeout int64) bool { return false }, +// }, mfs, 10) +// ui.(*UpgradeInspectorV5).SetOSDestDir("/home/ubuntu") +// err := ui.ShowInfo() +// assert.Equal(t, expected, tw.Output()) +// assert.NoError(t, err) +// } + +// func TestUpgradeInspectorV5ShowInfoWithNoInput(t *testing.T) { +// tw := majorupgrade_utils.NewCustomWriterWithInputs("n") +// mfs := &fileutils.MockFileSystemUtils{ +// CalDirSizeInGBFunc: CalDirSizeInGB, +// GetFreeSpaceinGBFunc: GetFreeSpaceinGB, +// GetHabRootPathFunc: GetHabRootPath, +// } +// ui := NewUpgradeInspectorV5(tw.CliWriter, &MockUpgradeV5UtilsImp{ +// IsExternalElasticSearchFunc: func(timeout int64) bool { return false }, +// }, mfs, 10) +// expected := fmt.Sprintf("%s\n\n%s\n\n%s\n", TITLE_MSG, RUN_WITH_OS_FLAG, PROCEED_CONF) +// expectedError := errors.New(UPGRADE_TERMINATED) +// err := ui.ShowInfo() +// assert.Equal(t, expected, tw.Output()) +// if assert.Error(t, err) { +// assert.Equal(t, expectedError.Error(), err.Error()) +// } +// } + +// func TestUpgradeInspectorV5ShowInfoWithInspections(t *testing.T) { +// tw := majorupgrade_utils.NewCustomWriterWithInputs("y") +// expected := fmt.Sprintf("%s\n\n%s\n\n%s\n\n%s\n", TITLE_MSG, INFO_MSG, RUN_WITH_OS_FLAG, PROCEED_CONF) + +// mfs := &fileutils.MockFileSystemUtils{ +// CalDirSizeInGBFunc: CalDirSizeInGB, +// GetFreeSpaceinGBFunc: GetFreeSpaceinGB, +// GetHabRootPathFunc: GetHabRootPath, +// } +// ui := NewUpgradeInspectorV5(tw.CliWriter, &MockUpgradeV5UtilsImp{ +// IsExternalElasticSearchFunc: func(timeout int64) bool { return false }, +// GetESBasePathFunc: func(timeout int64) string { return "http://localhost:10144/" }, +// }, mfs, 10) +// ui.(*UpgradeInspectorV5).AddDefaultInspections() + +// err := ui.ShowInfo() +// assert.Equal(t, expected, tw.Output()) +// assert.NoError(t, err) +// } + +// func TestUpgradeInspectorV5ShowInfoWithInspectionsWithFilesystemError(t *testing.T) { +// tw := majorupgrade_utils.NewCustomWriterWithInputs("y") +// expected := fmt.Sprintf(`%s + +// Before proceeding, please ensure: +// 1. You have scheduled downtime for the duration of the upgrade. +// 2. You have taken a backup by running the command: chef automate backup create. +// `, TITLE_MSG) +// mfs := &fileutils.MockFileSystemUtils{ +// CalDirSizeInGBFunc: CalDirSizeInGBError, +// GetFreeSpaceinGBFunc: GetFreeSpaceinGB, +// GetHabRootPathFunc: GetHabRootPath, +// } +// ui := NewUpgradeInspectorV5(tw.CliWriter, &MockUpgradeV5UtilsImp{ +// IsExternalElasticSearchFunc: func(timeout int64) bool { return false }, +// GetESBasePathFunc: func(timeout int64) string { return "http://localhost:10144/" }, +// }, mfs, 10) +// ui.(*UpgradeInspectorV5).AddDefaultInspections() +// err := ui.ShowInfo() +// assert.Equal(t, expected, tw.Output()) +// if assert.Error(t, err) { +// assert.Equal(t, "failed to check filesystem", err.Error()) +// } + +// } + +// func TestUpgradeInspectorV5ShowInfoInvalidInputError(t *testing.T) { +// tw := majorupgrade_utils.NewCustomWriterWithInputs("t") +// expected := fmt.Sprintf(`%s + +// %s +// I don't understand 't'. Please type 'y' or 'n'. +// Would you like to proceed with the upgrade? (y/n) +// `, TITLE_MSG, PROCEED_CONF) +// mfs := &fileutils.MockFileSystemUtils{ +// CalDirSizeInGBFunc: CalDirSizeInGB, +// GetFreeSpaceinGBFunc: GetFreeSpaceinGB, +// GetHabRootPathFunc: GetHabRootPath, +// } +// ui := NewUpgradeInspectorV5(tw.CliWriter, &MockUpgradeV5UtilsImp{ +// IsExternalElasticSearchFunc: func(timeout int64) bool { return false }, +// }, mfs, 10) +// ui.(*UpgradeInspectorV5).SetOSDestDir("/home/ubuntu") +// err := ui.ShowInfo() +// assert.Equal(t, expected, tw.Output()) +// if assert.Error(t, err) { +// assert.Equal(t, "failed to read user input in confirmation: EOF", err.Error()) +// } +// } + +// func TestUpgradeInspectorV5Inspect(t *testing.T) { +// tw := majorupgrade_utils.NewCustomWriter() +// mfs := &fileutils.MockFileSystemUtils{ +// CalDirSizeInGBFunc: CalDirSizeInGB, +// GetFreeSpaceinGBFunc: GetFreeSpaceinGB, +// GetHabRootPathFunc: GetHabRootPath, +// } +// ui := NewUpgradeInspectorV5(tw.CliWriter, &MockUpgradeV5UtilsImp{ +// IsExternalElasticSearchFunc: func(timeout int64) bool { return false }, +// }, mfs, 10) +// ui.AddInspection(NewPlannedDownTimeInspection(tw.CliWriter)) +// ui.AddInspection(NewTakeBackupInspection(tw.CliWriter)) +// diskSpaceInspection := NewDiskSpaceInspection(tw.CliWriter, false, false, "", mfs) +// ui.AddInspection(diskSpaceInspection) +// diskSpaceInspection.habDir = "/hab" +// diskSpaceInspection.osDestDir = "/home/ubuntu" +// diskSpaceInspection.currentHabSpace = 8.5 +// diskSpaceInspection.requiredHabSpace = 5.5 +// diskSpaceInspection.currentSpaceInOSDir = 8.5 +// diskSpaceInspection.requiredOSDestSpace = 3.3 +// diskSpaceInspection.checkDelay = 100 * time.Millisecond + +// expectedChecks := "Pre flight checks" +// expectedBeginHabChecking := "┤ [Checking]\tThe /hab directory should have at least 5.5GB of free space" +// expectedBeginOSDestChecking := "┤ [Checking]\tThe /home/ubuntu directory should have at least 3.3GB of free space" +// expectedPassHabChecking := "✔ [Passed]\tThe /hab directory should have at least 5.5GB of free space" +// expectedPassOSDestChecking := "✔ [Passed]\tThe /home/ubuntu directory should have at least 3.3GB of free space" + +// err := ui.Inspect() +// assert.Contains(t, tw.Output(), expectedChecks) +// assert.Contains(t, tw.Output(), expectedBeginHabChecking) +// assert.Contains(t, tw.Output(), expectedBeginOSDestChecking) +// assert.Contains(t, tw.Output(), expectedPassHabChecking) +// assert.Contains(t, tw.Output(), expectedPassOSDestChecking) +// assert.NoError(t, err) +// } + +// func TestUpgradeInspectorV5InspectHabFailed(t *testing.T) { +// tw := majorupgrade_utils.NewCustomWriter() +// mfs := &fileutils.MockFileSystemUtils{ +// CalDirSizeInGBFunc: CalDirSizeInGB, +// GetFreeSpaceinGBFunc: GetFreeSpaceinGB, +// GetHabRootPathFunc: GetHabRootPath, +// } +// ui := NewUpgradeInspectorV5(tw.CliWriter, &MockUpgradeV5UtilsImp{ +// IsExternalElasticSearchFunc: func(timeout int64) bool { return false }, +// }, mfs, 10) +// ui.AddInspection(NewPlannedDownTimeInspection(tw.CliWriter)) +// ui.AddInspection(NewTakeBackupInspection(tw.CliWriter)) +// diskSpaceInspection := NewDiskSpaceInspection(tw.CliWriter, false, false, "", mfs) +// ui.AddInspection(diskSpaceInspection) +// diskSpaceInspection.habDir = "/hab" +// diskSpaceInspection.osDestDir = "/home/ubuntu" +// diskSpaceInspection.currentHabSpace = 8.5 +// diskSpaceInspection.requiredHabSpace = 10.5 +// diskSpaceInspection.currentSpaceInOSDir = 8.5 +// diskSpaceInspection.requiredOSDestSpace = 3.3 +// diskSpaceInspection.checkDelay = 100 * time.Millisecond + +// expectedChecks := "Pre flight checks" +// expectedBeginHabChecking := "┤ [Checking]\tThe /hab directory should have at least 10.5GB of free space" +// expectedPassHabChecking := "✖ [Failed]\tThe /hab directory should have at least 10.5GB of free space" +// expectedPassOSDestChecking := "⊖ [Skipped]\tThe /home/ubuntu directory should have at least 3.3GB of free space" +// expectedEnsureSpace := "Please ensure the available free space is 10.5GB" + +// err := ui.Inspect() +// assert.Error(t, err) +// err = ui.RunExitAction() +// assert.NoError(t, err) +// assert.Contains(t, tw.Output(), expectedChecks) +// assert.Contains(t, tw.Output(), expectedBeginHabChecking) +// assert.Contains(t, tw.Output(), expectedPassHabChecking) +// assert.Contains(t, tw.Output(), expectedPassOSDestChecking) +// assert.Contains(t, tw.Output(), expectedEnsureSpace) +// } + +// func TestUpgradeInspectorV5InspectOSDestFailed(t *testing.T) { +// tw := majorupgrade_utils.NewCustomWriter() +// mfs := &fileutils.MockFileSystemUtils{ +// CalDirSizeInGBFunc: CalDirSizeInGB, +// GetFreeSpaceinGBFunc: GetFreeSpaceinGB, +// GetHabRootPathFunc: GetHabRootPath, +// } +// ui := NewUpgradeInspectorV5(tw.CliWriter, &MockUpgradeV5UtilsImp{ +// IsExternalElasticSearchFunc: func(timeout int64) bool { return false }, +// }, mfs, 10) +// ui.AddInspection(NewPlannedDownTimeInspection(tw.CliWriter)) +// ui.AddInspection(NewTakeBackupInspection(tw.CliWriter)) +// diskSpaceInspection := NewDiskSpaceInspection(tw.CliWriter, false, false, "", mfs) +// ui.AddInspection(diskSpaceInspection) +// diskSpaceInspection.habDir = "/hab" +// diskSpaceInspection.osDestDir = "/home/ubuntu" +// diskSpaceInspection.currentHabSpace = 8.5 +// diskSpaceInspection.requiredHabSpace = 5.5 +// diskSpaceInspection.currentSpaceInOSDir = 8.5 +// diskSpaceInspection.requiredOSDestSpace = 10.5 +// diskSpaceInspection.checkDelay = 100 * time.Millisecond + +// expectedChecks := "Pre flight checks" +// expectedBeginHabChecking := "┤ [Checking]\tThe /hab directory should have at least 5.5GB of free space" +// expectedBeginOSDestChecking := "┤ [Checking]\tThe /home/ubuntu directory should have at least 10.5GB of free space" +// expectedPassHabChecking := "✔ [Passed]\tThe /hab directory should have at least 5.5GB of free space" +// expectedPassOSDestChecking := "✖ [Failed]\tThe /home/ubuntu directory should have at least 10.5GB of free space" +// expectedEnsureSpace := "Please ensure the available free space is 10.5GB" + +// err := ui.Inspect() +// assert.Error(t, err) +// err = ui.RunExitAction() +// assert.NoError(t, err) +// assert.Contains(t, tw.Output(), expectedChecks) +// assert.Contains(t, tw.Output(), expectedBeginHabChecking) +// assert.Contains(t, tw.Output(), expectedBeginOSDestChecking) +// assert.Contains(t, tw.Output(), expectedPassHabChecking) +// assert.Contains(t, tw.Output(), expectedPassOSDestChecking) +// assert.Contains(t, tw.Output(), expectedEnsureSpace) +// } + +// func TestUpgradeInspectorV5InspectShowInspectionListForOsDest(t *testing.T) { +// tw := majorupgrade_utils.NewCustomWriter() +// mfs := &fileutils.MockFileSystemUtils{ +// CalDirSizeInGBFunc: CalDirSizeInGB, +// GetFreeSpaceinGBFunc: GetFreeSpaceinGB, +// GetHabRootPathFunc: GetHabRootPath, +// } +// ui := NewUpgradeInspectorV5(tw.CliWriter, &MockUpgradeV5UtilsImp{ +// IsExternalElasticSearchFunc: func(timeout int64) bool { return false }, +// }, mfs, 10) +// ui.AddInspection(NewPlannedDownTimeInspection(tw.CliWriter)) +// ui.AddInspection(NewTakeBackupInspection(tw.CliWriter)) +// diskSpaceInspection := NewDiskSpaceInspection(tw.CliWriter, false, false, "", mfs) +// ui.AddInspection(diskSpaceInspection) +// diskSpaceInspection.habDir = "/hab" +// diskSpaceInspection.osDestDir = "/home/ubuntu" +// diskSpaceInspection.currentHabSpace = 8.5 +// diskSpaceInspection.requiredHabSpace = 5.5 +// diskSpaceInspection.currentSpaceInOSDir = 8.5 +// diskSpaceInspection.requiredOSDestSpace = 3.3 + +// expected := INSPECTION_LIST + +// ui.ShowInspectionList() +// assert.Contains(t, tw.Output(), expected) +// } + +// func TestUpgradeInspectorV5ShowInspectionListForExternal(t *testing.T) { +// tw := majorupgrade_utils.NewCustomWriterWithInputs("y", "1") +// mfs := &fileutils.MockFileSystemUtils{ +// CalDirSizeInGBFunc: CalDirSizeInGB, +// GetFreeSpaceinGBFunc: GetFreeSpaceinGBToPassTest, +// GetHabRootPathFunc: GetHabRootPath, +// } +// ui := NewUpgradeInspectorV5(tw.CliWriter, &MockUpgradeV5UtilsImp{ +// IsExternalElasticSearchFunc: func(timeout int64) bool { return true }, +// GetESBasePathFunc: func(timeout int64) string { return "http://localhost:10144/" }, +// GetBackupS3URLFunc: func(timeout int64) (string, error) { +// return "https://s3.us-east-1.amazonaws.com", nil +// }, +// PatchS3backupURLFunc: func(timeout int64) (stdOut, stdErr string, err error) { +// return "", "", nil +// }, +// GetMaintenanceStatusFunc: func(timeout int64) (bool, error) { +// return false, nil +// }, +// SetMaintenanceModeFunc: func(timeout int64, status bool) (stdOut, stdErr string, err error) { +// return "", "", nil +// }, +// }, mfs, 10) + +// ui.(*UpgradeInspectorV5).AddDefaultInspections() + +// expected := "Following Pre-flight checks will be conducted\n1. The /hab directory should have at least 5.5GB of free space" + +// ui.ShowInfo() +// ui.ShowInspectionList() +// assert.Contains(t, tw.Output(), expected) +// } + +// func TestUpgradeInspectorV5ShowInspectionListForEmbedded(t *testing.T) { +// tw := majorupgrade_utils.NewCustomWriterWithInputs("y", "1") +// mfs := &fileutils.MockFileSystemUtils{ +// CalDirSizeInGBFunc: CalDirSizeInGB, +// GetFreeSpaceinGBFunc: GetFreeSpaceinGBToPassTest, +// GetHabRootPathFunc: GetHabRootPath, +// } +// ui := NewUpgradeInspectorV5(tw.CliWriter, &MockUpgradeV5UtilsImp{ +// IsExternalElasticSearchFunc: func(timeout int64) bool { return false }, +// GetESBasePathFunc: func(timeout int64) string { return "http://localhost:10144/" }, +// GetBackupS3URLFunc: func(timeout int64) (string, error) { +// return "https://s3.us-east-1.amazonaws.com", nil +// }, +// PatchS3backupURLFunc: func(timeout int64) (stdOut, stdErr string, err error) { +// return "", "", nil +// }, +// GetMaintenanceStatusFunc: func(timeout int64) (bool, error) { +// return false, nil +// }, +// SetMaintenanceModeFunc: func(timeout int64, status bool) (stdOut, stdErr string, err error) { +// return "", "", nil +// }, +// }, mfs, 10) + +// ui.(*UpgradeInspectorV5).AddDefaultInspections() + +// expected := "Following Pre-flight checks will be conducted\n1. The /hab directory should have at least 8.8GB of free space" + +// ui.ShowInfo() +// ui.ShowInspectionList() +// assert.Contains(t, tw.Output(), expected) +// } + +// func TestUpgradeInspectorV5RunInspectForOsDestDirSkipped(t *testing.T) { +// tw := majorupgrade_utils.NewCustomWriterWithInputs("y", "1") +// mfs := &fileutils.MockFileSystemUtils{ +// CalDirSizeInGBFunc: CalDirSizeInGB, +// GetFreeSpaceinGBFunc: GetFreeSpaceinGB, +// GetHabRootPathFunc: GetHabRootPath, +// } +// ui := NewUpgradeInspectorV5(tw.CliWriter, &MockUpgradeV5UtilsImp{ +// IsExternalElasticSearchFunc: func(timeout int64) bool { return false }, +// GetESBasePathFunc: func(timeout int64) string { return "http://localhost:10144/" }, +// ExecRequestFunc: NewUpgradeV5Utils().ExecRequest, +// GetBackupS3URLFunc: func(timeout int64) (string, error) { +// return "https://s3.us-east-1.amazonaws.com", nil +// }, +// PatchS3backupURLFunc: func(timeout int64) (stdOut, stdErr string, err error) { +// return "", "", nil +// }, +// GetMaintenanceStatusFunc: func(timeout int64) (bool, error) { +// return false, nil +// }, +// SetMaintenanceModeFunc: func(timeout int64, status bool) (stdOut, stdErr string, err error) { +// return "", "", nil +// }, +// GetServicesStatusFunc: func() (bool, error) { +// return true, nil +// }, +// }, mfs, 10) + +// ui.(*UpgradeInspectorV5).SetOSDestDir("/home/ubuntu") +// ui.(*UpgradeInspectorV5).AddDefaultInspections() + +// expected1 := "[Skipped]\tThe /home/ubuntu directory should have at least 3.3GB of free space" +// expected2 := "[Skipped]\tElasticsearch indices are in version 6\n" + +// ui.ShowInfo() +// ui.ShowInspectionList() +// ui.Inspect() +// assert.Contains(t, tw.Output(), expected1) +// assert.Contains(t, tw.Output(), expected2) +// } + +// func TestUpgradeInspectorV5ExitMessage(t *testing.T) { +// tw := majorupgrade_utils.NewCustomWriterWithInputs("y", "1") +// mfs := &fileutils.MockFileSystemUtils{ +// CalDirSizeInGBFunc: CalDirSizeInGB, +// GetFreeSpaceinGBFunc: GetFreeSpaceinGB, +// GetHabRootPathFunc: GetHabRootPath, +// WriteToFileFunc: func(filepath string, data []byte) error { return nil }, +// } +// ui := NewUpgradeInspectorV5(tw.CliWriter, &MockUpgradeV5UtilsImp{ +// IsExternalElasticSearchFunc: func(timeout int64) bool { return false }, +// GetESBasePathFunc: func(timeout int64) string { return "http://localhost:10144/" }, +// GetBackupS3URLFunc: func(timeout int64) (string, error) { +// return "https://s3.us-east-1.amazonaws.com", nil +// }, +// PatchS3backupURLFunc: func(timeout int64) (stdOut, stdErr string, err error) { +// return "", "", nil +// }, +// GetMaintenanceStatusFunc: func(timeout int64) (bool, error) { +// return false, nil +// }, +// SetMaintenanceModeFunc: func(timeout int64, status bool) (stdOut, stdErr string, err error) { +// return "", "", nil +// }, +// GetServicesStatusFunc: func() (bool, error) { +// return true, nil +// }, +// ExecRequestFunc: NewUpgradeV5Utils().ExecRequest, +// }, mfs, 10) + +// expected := HAB_SPACE_ERR + +// err := ui.RunUpgradeInspector("", false) +// assert.True(t, err) +// assert.Contains(t, tw.Output(), expected) +// } + +// func TestUpgradeInspectorV5ExitMessageFailedMaintenance(t *testing.T) { +// tw := majorupgrade_utils.NewCustomWriterWithInputs("y", "1") +// mfs := &fileutils.MockFileSystemUtils{ +// CalDirSizeInGBFunc: CalDirSizeInGB, +// GetFreeSpaceinGBFunc: GetFreeSpaceinGBToPassTest, +// GetHabRootPathFunc: GetHabRootPath, +// WriteToFileFunc: func(filepath string, data []byte) error { return nil }, +// } +// shardingCalledCount := 0 +// ui := NewUpgradeInspectorV5(tw.CliWriter, &MockUpgradeV5UtilsImp{ +// IsExternalElasticSearchFunc: func(timeout int64) bool { return false }, +// GetESBasePathFunc: func(timeout int64) string { return "http://localhost:10144/" }, +// GetBackupS3URLFunc: func(timeout int64) (string, error) { +// return "https://s3.us-east-1.amazonaws.com", nil +// }, +// PatchS3backupURLFunc: func(timeout int64) (stdOut, stdErr string, err error) { +// return "", "", nil +// }, +// GetMaintenanceStatusFunc: func(timeout int64) (bool, error) { +// return false, errors.New("unreachable") +// }, +// SetMaintenanceModeFunc: func(timeout int64, status bool) (stdOut, stdErr string, err error) { +// return "", "", nil +// }, +// GetServicesStatusFunc: func() (bool, error) { +// return true, nil +// }, +// ExecRequestFunc: func(url, methodType string, requestBody io.Reader) ([]byte, error) { +// if strings.Contains(url, "_cluster/settings") { +// shardingCalledCount++ +// return []byte{}, nil +// } else if strings.Contains(url, "index.version") { +// return []byte(`{"node-attribute":{"settings":{"index":{"version":{"created_string":"5.8.23","created":"6082399"}}}},"comp-2-run-info":{"settings":{"index":{"version":{"created_string":"5.8.23","created":"6082399"}}}}}`), nil +// } else if strings.Contains(url, "_cluster/stats") { +// return []byte(`{"indices":{"shards":{"total":51}}}`), nil +// } else if strings.Contains(url, "indices") { +// return []byte(INDEX_LIST), nil +// } else { +// return []byte{}, nil +// } +// }, +// }, mfs, 10) + +// ui.(*UpgradeInspectorV5).AddDefaultInspections() + +// expected := `[Error] unreachable` + +// err := ui.ShowInfo() +// assert.NoError(t, err) +// ui.ShowInspectionList() +// err = ui.Inspect() +// assert.Error(t, err) +// err = ui.RollBackChangesOnError() +// assert.NoError(t, err) +// err = ui.RunExitAction() +// assert.NoError(t, err) +// assert.Equal(t, 2, shardingCalledCount) +// assert.Contains(t, tw.Output(), expected) +// } + +// func TestUpgradeInspectorV5SkipAllEnsureStatusFailure(t *testing.T) { +// tw := majorupgrade_utils.NewCustomWriterWithInputs("y", "1") +// mfs := &fileutils.MockFileSystemUtils{ +// CalDirSizeInGBFunc: CalDirSizeInGB, +// GetFreeSpaceinGBFunc: GetFreeSpaceinGBToPassTest, +// GetHabRootPathFunc: GetHabRootPath, +// WriteToFileFunc: func(filepath string, data []byte) error { return nil }, +// } +// shardingCalledCount := 0 +// ui := NewUpgradeInspectorV5(tw.CliWriter, &MockUpgradeV5UtilsImp{ +// IsExternalElasticSearchFunc: func(timeout int64) bool { return false }, +// GetESBasePathFunc: func(timeout int64) string { return "http://localhost:10144/" }, +// GetBackupS3URLFunc: func(timeout int64) (string, error) { +// return "https://s3.us-east-1.amazonaws.com", nil +// }, +// PatchS3backupURLFunc: func(timeout int64) (stdOut, stdErr string, err error) { +// return "", "", nil +// }, +// GetMaintenanceStatusFunc: func(timeout int64) (bool, error) { +// return false, errors.New("unreachable") +// }, +// SetMaintenanceModeFunc: func(timeout int64, status bool) (stdOut, stdErr string, err error) { +// return "", "", nil +// }, +// GetServicesStatusFunc: func() (bool, error) { +// return false, nil +// }, +// ExecRequestFunc: func(url, methodType string, requestBody io.Reader) ([]byte, error) { +// if strings.Contains(url, "_cluster/settings") { +// shardingCalledCount++ +// return []byte{}, nil +// } else if strings.Contains(url, "index.version") { +// return []byte(`{"node-attribute":{"settings":{"index":{"version":{"created_string":"5.8.23","created":"6082399"}}}},"comp-2-run-info":{"settings":{"index":{"version":{"created_string":"5.8.23","created":"6082399"}}}}}`), nil +// } else if strings.Contains(url, "_cluster/stats") { +// return []byte(`{"indices":{"shards":{"total":51}}}`), nil +// } else if strings.Contains(url, "indices") { +// return []byte(INDEX_LIST), nil +// } else { +// return []byte{}, nil +// } +// }, +// }, mfs, 10) + +// expected := ALL_SKIPPED_OS + +// iserr := ui.RunUpgradeInspector("/home/ubuntu", false) +// assert.Equal(t, iserr, true) +// assert.Contains(t, tw.Output(), expected) +// } diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/utils.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/utils.go new file mode 100644 index 00000000000..9313c170b3a --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/utils.go @@ -0,0 +1,88 @@ +package upgradeinspectorv5 + +import ( + "fmt" + "io" + "net/http" + + "github.com/chef/automate/components/automate-deployment/pkg/majorupgradechecklist" + "github.com/chef/automate/lib/majorupgrade_utils" + "github.com/pkg/errors" +) + +type UpgradeV5Utils interface { + IsExternalOpenSearch(timeout int64) bool + IsExternalPG() bool + ExecRequest(url, methodType string, requestBody io.Reader) ([]byte, error) + GetMaintenanceStatus(timeout int64) (bool, error) + SetMaintenanceMode(timeout int64, status bool) (stdOut, stdErr string, err error) + GetServicesStatus() (bool, error) +} + +const ( + downTimeError = "There will be a downtime while upgrading. Please prepare for down time and run the upgrade" + + backupError = "Please take a backup and restart the upgrade process." + + diskSpaceError = `Please ensure to have %.2f GB free disk space` + + postChecklistIntimationError = "Post upgrade steps need to be run, after this upgrade completed." + + reindexingError = "Please do reindexing and restart the upgrade process." + + NEW_S3_URL = "https://s3.amazonaws.com" +) + +type UpgradeV5UtilsImp struct{} + +func NewUpgradeV5Utils() UpgradeV5Utils { + return &UpgradeV5UtilsImp{} +} + +func (cu *UpgradeV5UtilsImp) GetMaintenanceStatus(timeout int64) (bool, error) { + return majorupgrade_utils.GetMaintenanceStatus(timeout) +} + +func (cu *UpgradeV5UtilsImp) SetMaintenanceMode(timeout int64, status bool) (stdOut, stdErr string, err error) { + return majorupgrade_utils.SetMaintenanceMode(timeout, status) +} + +func (cu *UpgradeV5UtilsImp) IsExternalOpenSearch(timeout int64) bool { + return majorupgrade_utils.IsExternalOpenSearch(timeout) +} + +func (cu *UpgradeV5UtilsImp) IsExternalPG() bool { + return majorupgradechecklist.IsExternalPG() +} + +func (cu *UpgradeV5UtilsImp) ExecRequest(url, methodType string, requestBody io.Reader) ([]byte, error) { + method := methodType + + client := &http.Client{} + req, err := http.NewRequest(method, url, requestBody) // nosemgrep + + if err != nil { + return nil, err + } + req.Header.Add("Content-Type", "application/json") + + res, err := client.Do(req) + if err != nil { + fmt.Println(err) + return nil, err + } + defer res.Body.Close() + body, err := io.ReadAll(res.Body) // nosemgrep + if err != nil { + return nil, err + } + + if res.StatusCode != http.StatusOK { + return nil, errors.Errorf("Request failed with status %d\n%s\n", res.StatusCode, string(body)) + } + return body, nil +} + +func (cu *UpgradeV5UtilsImp) GetServicesStatus() (bool, error) { + return majorupgrade_utils.EnsureStatus() +} diff --git a/components/automate-deployment/pkg/inspector/upgradeinspectorv5/utilsmock.go b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/utilsmock.go new file mode 100644 index 00000000000..35a58e5057c --- /dev/null +++ b/components/automate-deployment/pkg/inspector/upgradeinspectorv5/utilsmock.go @@ -0,0 +1,33 @@ +package upgradeinspectorv5 + +import ( + "io" +) + +type MockUpgradeV5UtilsImp struct { + IsExternalOpenSearchFunc func(timeout int64) bool + IsExternalPGFunc func() bool + ExecRequestFunc func(url, methodType string, requestBody io.Reader) ([]byte, error) + GetMaintenanceStatusFunc func(timeout int64) (bool, error) + SetMaintenanceModeFunc func(timeout int64, status bool) (stdOut, stdErr string, err error) + GetServicesStatusFunc func() (bool, error) +} + +func (utl *MockUpgradeV5UtilsImp) IsExternalOpenSearch(timeout int64) bool { + return utl.IsExternalOpenSearchFunc(timeout) +} +func (utl *MockUpgradeV5UtilsImp) IsExternalPG() bool { + return utl.IsExternalPGFunc() +} +func (utl *MockUpgradeV5UtilsImp) ExecRequest(url, methodType string, requestBody io.Reader) ([]byte, error) { + return utl.ExecRequestFunc(url, methodType, requestBody) +} +func (utl *MockUpgradeV5UtilsImp) GetMaintenanceStatus(timeout int64) (bool, error) { + return utl.GetMaintenanceStatusFunc(timeout) +} +func (utl *MockUpgradeV5UtilsImp) SetMaintenanceMode(timeout int64, status bool) (stdOut, stdErr string, err error) { + return utl.SetMaintenanceModeFunc(timeout, status) +} +func (utl *MockUpgradeV5UtilsImp) GetServicesStatus() (bool, error) { + return utl.GetServicesStatusFunc() +} diff --git a/lib/majorupgrade_utils/utils.go b/lib/majorupgrade_utils/utils.go index 04f910ec51b..3667b0141a4 100644 --- a/lib/majorupgrade_utils/utils.go +++ b/lib/majorupgrade_utils/utils.go @@ -27,6 +27,14 @@ func IsExternalElasticSearch(timeout int64) bool { return res.Config.GetGlobal().GetV1().GetExternal().GetElasticsearch().GetEnable().GetValue() } +func IsExternalOpenSearch(timeout int64) bool { + res, err := client.GetAutomateConfig(timeout) + if err != nil { + return false + } + return res.Config.GetGlobal().GetV1().GetExternal().GetOpensearch().GetEnable().GetValue() +} + func SetMaintenanceMode(timeout int64, status bool) (stdOut, stdErr string, err error) { currentStatus, err := GetMaintenanceStatus(timeout) if err != nil { diff --git a/results/.gitkeep b/results/.gitkeep deleted file mode 100644 index e69de29bb2d..00000000000