diff --git a/tests/e2e/test_rosacli_cluster.go b/tests/e2e/test_rosacli_cluster.go index f42b243b32..d69ad63371 100644 --- a/tests/e2e/test_rosacli_cluster.go +++ b/tests/e2e/test_rosacli_cluster.go @@ -29,6 +29,7 @@ var _ = Describe("Edit cluster", clusterID string rosaClient *rosacli.Client clusterService rosacli.ClusterService + upgradeService rosacli.UpgradeService clusterConfig *config.ClusterConfig ) @@ -40,6 +41,7 @@ var _ = Describe("Edit cluster", By("Init the client") rosaClient = rosacli.NewClient() clusterService = rosaClient.Cluster + upgradeService = rosaClient.Upgrade By("Load the original cluster config") var err error @@ -228,19 +230,19 @@ var _ = Describe("Edit cluster", labels.Medium, labels.Runtime.Day2, func() { By("Validate that deletion of upgrade policy for rosa cluster will work via rosacli") - output, err := clusterService.DeleteUpgrade() + output, err := upgradeService.DeleteUpgrade() Expect(err).To(HaveOccurred()) textData := rosaClient.Parser.TextData.Input(output).Parse().Tip() Expect(textData).Should(ContainSubstring(`required flag(s) "cluster" not set`)) By("Delete an non-existent upgrade when cluster has no scheduled policy") - output, err = clusterService.DeleteUpgrade("-c", clusterID) + output, err = upgradeService.DeleteUpgrade("-c", clusterID) Expect(err).ToNot(HaveOccurred()) textData = rosaClient.Parser.TextData.Input(output).Parse().Tip() Expect(textData).Should(ContainSubstring(`There are no scheduled upgrades on cluster '%s'`, clusterID)) By("Delete with unknown flag --interactive") - output, err = clusterService.DeleteUpgrade("-c", clusterID, "--interactive") + output, err = upgradeService.DeleteUpgrade("-c", clusterID, "--interactive") Expect(err).To(HaveOccurred()) textData = rosaClient.Parser.TextData.Input(output).Parse().Tip() Expect(textData).Should(ContainSubstring("Error: unknown flag: --interactive")) @@ -250,7 +252,7 @@ var _ = Describe("Edit cluster", labels.Medium, labels.Runtime.Day2, func() { defer func() { - _, err := clusterService.DeleteUpgrade("-c", clusterID, "-y") + _, err := upgradeService.DeleteUpgrade("-c", clusterID, "-y") Expect(err).ToNot(HaveOccurred()) }() @@ -262,7 +264,7 @@ var _ = Describe("Edit cluster", } By("Upgrade cluster without --control-plane flag") - output, err := clusterService.Upgrade("-c", clusterID) + output, err := upgradeService.Upgrade("-c", clusterID) Expect(err).To(HaveOccurred()) textData := rosaClient.Parser.TextData.Input(output).Parse().Tip() Expect(textData). @@ -271,7 +273,7 @@ var _ = Describe("Edit cluster", By("Upgrade cluster with invalid cluster id") invalidClusterID := common.GenerateRandomString(30) - output, err = clusterService.Upgrade("-c", invalidClusterID) + output, err = upgradeService.Upgrade("-c", invalidClusterID) Expect(err).To(HaveOccurred()) textData = rosaClient.Parser.TextData.Input(output).Parse().Tip() Expect(textData). @@ -281,7 +283,7 @@ var _ = Describe("Edit cluster", invalidClusterID)) By("Upgrade cluster with incorrect format of the date and time") - output, err = clusterService.Upgrade( + output, err = upgradeService.Upgrade( "-c", clusterID, "--control-plane", "--mode=auto", @@ -293,7 +295,7 @@ var _ = Describe("Edit cluster", Expect(textData).To(ContainSubstring("ERR: schedule date should use the format 'yyyy-mm-dd'")) By("Upgrade cluster using --schedule, --schedule-date and --schedule-time flags at the same time") - output, err = clusterService.Upgrade( + output, err = upgradeService.Upgrade( "-c", clusterID, "--control-plane", "--mode=auto", @@ -308,7 +310,7 @@ var _ = Describe("Edit cluster", "ERR: The '--schedule-date' and '--schedule-time' options are mutually exclusive with '--schedule'")) By("Upgrade cluster using --schedule and --version flags at the same time") - output, err = clusterService.Upgrade( + output, err = upgradeService.Upgrade( "-c", clusterID, "--control-plane", "--mode=auto", @@ -322,7 +324,7 @@ var _ = Describe("Edit cluster", "ERR: The '--schedule' option is mutually exclusive with '--version'")) By("Upgrade cluster with value not match the cron epression") - output, err = clusterService.Upgrade( + output, err = upgradeService.Upgrade( "-c", clusterID, "--control-plane", "--mode=auto", diff --git a/tests/e2e/test_rosacli_upgrade.go b/tests/e2e/test_rosacli_upgrade.go index 224e5b8184..e3c277d5db 100644 --- a/tests/e2e/test_rosacli_upgrade.go +++ b/tests/e2e/test_rosacli_upgrade.go @@ -26,6 +26,7 @@ var _ = Describe("Cluster Upgrade testing", rosaClient *rosacli.Client arbitraryPolicyService rosacli.PolicyService clusterService rosacli.ClusterService + upgradeService rosacli.UpgradeService arbitraryPoliciesToClean []string awsClient *aws_client.AWSClient profile *profilehandler.Profile @@ -40,6 +41,7 @@ var _ = Describe("Cluster Upgrade testing", rosaClient = rosacli.NewClient() arbitraryPolicyService = rosaClient.Policy clusterService = rosaClient.Cluster + upgradeService = rosaClient.Upgrade By("Load the profile") profile = profilehandler.LoadProfileYamlFileByENV() @@ -248,14 +250,14 @@ var _ = Describe("Cluster Upgrade testing", // It needs to add step to wait the cluster upgrade done // and to check the `rosa describe/list upgrade` in both of these two case. if !isHosted { - output, err = clusterService.Upgrade( + output, err = upgradeService.Upgrade( "-c", clusterID, "--version", upgradingVersion, "--mode", "auto", "-y", ) } else { - output, err = clusterService.Upgrade( + output, err = upgradeService.Upgrade( "-c", clusterID, "--version", upgradingVersion, "--mode", "auto", "--hosted-cp", @@ -296,7 +298,7 @@ var _ = Describe("Cluster Upgrade testing", upgradingVersion := versions[0] By("Upgrade cluster") - output, err := clusterService.Upgrade( + output, err := upgradeService.Upgrade( "-c", clusterID, "--version", upgradingVersion, "--schedule-date", scheduledDate, @@ -307,17 +309,150 @@ var _ = Describe("Cluster Upgrade testing", Expect(output.String()).To(ContainSubstring("Upgrade successfully scheduled for cluster")) By("Check upgrade state") - err = WaitForUpgradeToState(clusterService, clusterID, con.Scheduled, 4) + err = WaitForUpgradeToState(upgradeService, clusterID, con.Scheduled, 4) Expect(err).To(BeNil()) - err = WaitForUpgradeToState(clusterService, clusterID, con.Started, 70) + err = WaitForUpgradeToState(upgradeService, clusterID, con.Started, 70) Expect(err).To(BeNil()) }) }) -func WaitForUpgradeToState(c rosacli.ClusterService, clusterID string, state string, timeout int) error { +var _ = Describe("Describe/List rosa upgrade", + labels.Feature.Cluster, func() { + defer GinkgoRecover() + var ( + rosaClient *rosacli.Client + clusterService rosacli.ClusterService + upgradeService rosacli.UpgradeService + clusterID string + profile *profilehandler.Profile + ) + + BeforeEach(func() { + By("Get the cluster") + clusterID = config.GetClusterID() + Expect(clusterID).ToNot(Equal(""), "ClusterID is required. Please export CLUSTER_ID") + + By("Init the client") + rosaClient = rosacli.NewClient() + clusterService = rosaClient.Cluster + upgradeService = rosaClient.Upgrade + + By("Load the profile") + profile = profilehandler.LoadProfileYamlFileByENV() + }) + + AfterEach(func() { + if profile.Version == con.YStreamPreviousVersion { + By("Delete cluster upgrade") + output, err := upgradeService.DeleteUpgrade("-c", clusterID, "-y") + Expect(err).ToNot(HaveOccurred()) + Expect(output.String()).To(ContainSubstring("Successfully canceled scheduled upgrade on cluster "+ + "'%s'", clusterID)) + } + + By("Clean remaining resources") + err := rosaClient.CleanResources(clusterID) + Expect(err).ToNot(HaveOccurred()) + }) + + It("to list/describe rosa upgrade via ROSA CLI - [id:57094]", + labels.High, labels.Runtime.Day2, + func() { + By("Check the help message of 'rosa describe upgrade -h'") + output, err := upgradeService.DescribeUpgrade(clusterID, "-h") + Expect(err).To(BeNil()) + Expect(output.String()).To(ContainSubstring("rosa describe upgrade [flags]")) + Expect(output.String()).To(ContainSubstring("-c, --cluster")) + Expect(output.String()).To(ContainSubstring("--machinepool")) + Expect(output.String()).To(ContainSubstring("-y, --yes")) + + if profile.Version == "latest" { + By("Check list upgrade for the cluster with latest version") + output, err = upgradeService.ListUpgrades(clusterID) + Expect(err).To(BeNil()) + Expect(output.String()).To(ContainSubstring("There are no available upgrades for cluster "+ + "'%s'", clusterID)) + } + + if profile.Version == con.YStreamPreviousVersion { + By("Upgrade cluster and check list/describe upgrade") + scheduledDate := time.Now().Format("2006-01-02") + scheduledTime := time.Now().Add(20 * time.Minute).UTC().Format("15:04") + + jsonData, err := clusterService.GetJSONClusterDescription(clusterID) + Expect(err).To(BeNil()) + clusterVersion := jsonData.DigString("version", "raw_id") + + versionService := rosaClient.Version + clusterVersionList, err := versionService.ListAndReflectVersions(profile.ChannelGroup, false) + Expect(err).ToNot(HaveOccurred()) + + versions, err := clusterVersionList.FindYStreamUpgradeVersions(clusterVersion) + Expect(err).To(BeNil()) + if len(versions) == 0 { + Skip(fmt.Sprintf("No available upgrade version is found for the cluster version %s", + clusterVersion)) + } + upgradingVersion := versions[0] + + By("Upgrade cluster") + if profile.ClusterConfig.STS { + hostedCluster, err := clusterService.IsHostedCPCluster(clusterID) + Expect(err).ToNot(HaveOccurred()) + if !hostedCluster { + _, errSTSUpgrade := upgradeService.Upgrade( + "-c", clusterID, + "--version", upgradingVersion, + "--schedule-date", scheduledDate, + "--schedule-time", scheduledTime, + "-m", "auto", + "-y", + ) + Expect(errSTSUpgrade).To(BeNil()) + } else { + _, errHCPUpgrade := upgradeService.Upgrade( + "-c", clusterID, + "--version", upgradingVersion, + "--schedule-date", scheduledDate, + "--schedule-time", scheduledTime, + "-m", "auto", + "--control-plane", + "-y", + ) + Expect(errHCPUpgrade).To(BeNil()) + } + } else { + _, errUpgrade := upgradeService.Upgrade( + "-c", clusterID, + "--version", upgradingVersion, + "--schedule-date", scheduledDate, + "--schedule-time", scheduledTime, + "-y", + ) + Expect(errUpgrade).To(BeNil()) + } + + time.Sleep(2 * time.Minute) + By("Check list upgrade") + out, err := upgradeService.ListUpgrades(clusterID) + Expect(err).To(BeNil()) + Expect(out.String()).To(ContainSubstring("%s scheduled for %s %s UTC", upgradingVersion, + scheduledDate, scheduledTime)) + + By("Check describe upgrade") + UD, err := upgradeService.DescribeUpgradeAndReflect(clusterID) + Expect(err).To(BeNil()) + Expect(UD.ClusterID).To(Equal(clusterID)) + Expect(UD.NextRun).To(Equal(fmt.Sprintf("%s %s UTC", scheduledDate, scheduledTime))) + Expect(UD.UpgradeState).To(Equal("scheduled")) + } + }) + }) + +func WaitForUpgradeToState(u rosacli.UpgradeService, clusterID string, state string, timeout int) error { startTime := time.Now() for time.Now().Before(startTime.Add(time.Duration(timeout) * time.Minute)) { - UD, err := c.DescribeUpgradeAndReflect(clusterID) + UD, err := u.DescribeUpgradeAndReflect(clusterID) if err != nil { return err } else { diff --git a/tests/utils/common/constants/general.go b/tests/utils/common/constants/general.go index 4fb5150084..12bf1e60ed 100644 --- a/tests/utils/common/constants/general.go +++ b/tests/utils/common/constants/general.go @@ -1,8 +1,9 @@ package constants const ( - Yes = "Yes" - No = "No" + Yes = "Yes" + No = "No" + YStreamPreviousVersion = "y-1" ) // Ec2MetadataHttpTokens for hcp cluster diff --git a/tests/utils/exec/rosacli/cluster_service.go b/tests/utils/exec/rosacli/cluster_service.go index cd8a8cd5e1..40e58178a0 100644 --- a/tests/utils/exec/rosacli/cluster_service.go +++ b/tests/utils/exec/rosacli/cluster_service.go @@ -27,10 +27,6 @@ type ClusterService interface { DeleteCluster(clusterID string, flags ...string) (bytes.Buffer, error) CreateDryRun(clusterName string, flags ...string) (bytes.Buffer, error) EditCluster(clusterID string, flags ...string) (bytes.Buffer, error) - DeleteUpgrade(flags ...string) (bytes.Buffer, error) - Upgrade(flags ...string) (bytes.Buffer, error) - DescribeUpgrade(clusterID string, flags ...string) (bytes.Buffer, error) - DescribeUpgradeAndReflect(clusterID string) (*UpgradeDescription, error) InstallLog(clusterID string, flags ...string) (bytes.Buffer, error) UnInstallLog(clusterID string, flags ...string) (bytes.Buffer, error) @@ -72,14 +68,6 @@ type ClusterList struct { Clusters []ClusterListItem `yaml:"Clusters,omitempty"` } -// Struct for the 'rosa describe upgrade' output -type UpgradeDescription struct { - ID string `yaml:"ID,omitempty"` - ClusterID string `yaml:"Cluster ID,omitempty"` - NextRun string `yaml:"Next Run,omitempty"` - UpgradeState string `yaml:"Upgrade State,omitempty"` -} - // Struct for the 'rosa describe cluster' output type ClusterDescription struct { Name string `yaml:"Name,omitempty"` @@ -258,56 +246,6 @@ func (c *clusterService) EditCluster(clusterID string, flags ...string) (bytes.B return editCluster.Run() } -func (c *clusterService) DeleteUpgrade(flags ...string) (bytes.Buffer, error) { - DeleteUpgrade := c.client.Runner. - Cmd("delete", "upgrade"). - CmdFlags(flags...) - return DeleteUpgrade.Run() -} - -func (c *clusterService) Upgrade(flags ...string) (bytes.Buffer, error) { - upgrade := c.client.Runner. - Cmd("upgrade", "cluster"). - CmdFlags(flags...) - return upgrade.Run() -} - -func (c *clusterService) DescribeUpgrade(clusterID string, flags ...string) (bytes.Buffer, error) { - combflags := append([]string{"-c", clusterID}, flags...) - describe := c.client.Runner. - Cmd("describe", "upgrade"). - CmdFlags(combflags...) - return describe.Run() -} - -func (c *clusterService) DescribeUpgradeAndReflect(clusterID string) (res *UpgradeDescription, err error) { - output, err := c.DescribeUpgrade(clusterID) - if err != nil { - return nil, err - } - return c.ReflectUpgradeDescription(output) -} - -func (c *clusterService) ReflectUpgradeDescription(result bytes.Buffer) (res *UpgradeDescription, err error) { - var data []byte - res = new(UpgradeDescription) - theMap, err := c.client. - Parser. - TextData. - Input(result). - Parse(). - YamlToMap() - if err != nil { - return - } - data, err = yaml.Marshal(&theMap) - if err != nil { - return - } - err = yaml.Unmarshal(data, res) - return res, err -} - func (c *clusterService) InstallLog(clusterID string, flags ...string) (bytes.Buffer, error) { installLog := c.client.Runner. Cmd("logs", "install", "-c", clusterID). diff --git a/tests/utils/exec/rosacli/cmd_client.go b/tests/utils/exec/rosacli/cmd_client.go index 8c90aadfbb..446213def6 100644 --- a/tests/utils/exec/rosacli/cmd_client.go +++ b/tests/utils/exec/rosacli/cmd_client.go @@ -45,6 +45,7 @@ type Client struct { ExternalAuthProvider ExternalAuthProviderService Policy PolicyService AutoScaler AutoScalerService + Upgrade UpgradeService } func NewClient() *Client { @@ -72,6 +73,7 @@ func NewClient() *Client { client.ExternalAuthProvider = NewExternalAuthProviderService(client) client.Policy = NewPolicyService(client) client.AutoScaler = NewAutoScalerService(client) + client.Upgrade = NewUpgradeService(client) return client } @@ -95,6 +97,7 @@ func (c *Client) CleanResources(clusterID string) error { errorList = append(errorList, c.ExternalAuthProvider.CleanResources(clusterID)...) errorList = append(errorList, c.AutoScaler.CleanResources(clusterID)...) errorList = append(errorList, c.Policy.CleanResources(clusterID)...) + errorList = append(errorList, c.Upgrade.CleanResources(clusterID)...) return errors.Join(errorList...) diff --git a/tests/utils/exec/rosacli/upgrade_service.go b/tests/utils/exec/rosacli/upgrade_service.go new file mode 100644 index 0000000000..4da1a8a7fe --- /dev/null +++ b/tests/utils/exec/rosacli/upgrade_service.go @@ -0,0 +1,102 @@ +package rosacli + +import ( + "bytes" + + "gopkg.in/yaml.v3" + + "github.com/openshift/rosa/tests/utils/log" +) + +type UpgradeService interface { + ResourcesCleaner + + ListUpgrades(clusterID string, flags ...string) (bytes.Buffer, error) + DescribeUpgrade(clusterID string, flags ...string) (bytes.Buffer, error) + DescribeUpgradeAndReflect(clusterID string) (*UpgradeDescription, error) + DeleteUpgrade(flags ...string) (bytes.Buffer, error) + Upgrade(flags ...string) (bytes.Buffer, error) +} + +type upgradeService struct { + ResourcesService +} + +func NewUpgradeService(client *Client) UpgradeService { + return &upgradeService{ + ResourcesService: ResourcesService{ + client: client, + }, + } +} + +// Struct for the 'rosa describe upgrade' output +type UpgradeDescription struct { + ID string `yaml:"ID,omitempty"` + ClusterID string `yaml:"Cluster ID,omitempty"` + NextRun string `yaml:"Next Run,omitempty"` + UpgradeState string `yaml:"Upgrade State,omitempty"` +} + +func (u *upgradeService) ListUpgrades(clusterID string, flags ...string) (bytes.Buffer, error) { + combflags := append([]string{"--cluster", clusterID}, flags...) + describe := u.client.Runner. + Cmd("list", "upgrade"). + CmdFlags(combflags...) + return describe.Run() +} + +func (u *upgradeService) DescribeUpgrade(clusterID string, flags ...string) (bytes.Buffer, error) { + combflags := append([]string{"-c", clusterID}, flags...) + describe := u.client.Runner. + Cmd("describe", "upgrade"). + CmdFlags(combflags...) + return describe.Run() +} + +func (u *upgradeService) DescribeUpgradeAndReflect(clusterID string) (res *UpgradeDescription, err error) { + output, err := u.DescribeUpgrade(clusterID) + if err != nil { + return nil, err + } + return u.ReflectUpgradeDescription(output) +} + +func (u *upgradeService) ReflectUpgradeDescription(result bytes.Buffer) (res *UpgradeDescription, err error) { + var data []byte + res = new(UpgradeDescription) + theMap, err := u.client. + Parser. + TextData. + Input(result). + Parse(). + YamlToMap() + if err != nil { + return + } + data, err = yaml.Marshal(&theMap) + if err != nil { + return + } + err = yaml.Unmarshal(data, res) + return res, err +} + +func (u *upgradeService) DeleteUpgrade(flags ...string) (bytes.Buffer, error) { + DeleteUpgrade := u.client.Runner. + Cmd("delete", "upgrade"). + CmdFlags(flags...) + return DeleteUpgrade.Run() +} + +func (u *upgradeService) Upgrade(flags ...string) (bytes.Buffer, error) { + upgrade := u.client.Runner. + Cmd("upgrade", "cluster"). + CmdFlags(flags...) + return upgrade.Run() +} + +func (u *upgradeService) CleanResources(clusterID string) (errors []error) { + log.Logger.Debugf("Nothing to clean in Version Service") + return +}