-
Notifications
You must be signed in to change notification settings - Fork 4.8k
OCPBUGS-61063: test/extended/cli/adm_upgrade/recommend: Enable precheck and accept #30113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f5be161
533440d
7724a75
de10dfe
c68be5e
78ac50f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ import ( | |
| "fmt" | ||
| "net" | ||
| "net/url" | ||
| "os" | ||
| "strconv" | ||
| "strings" | ||
| "text/template" | ||
|
|
@@ -31,6 +32,7 @@ var _ = g.Describe("[Serial][sig-cli] oc adm upgrade recommend", g.Ordered, func | |
| oc := exutil.NewCLIWithFramework(f).AsAdmin() | ||
| var cv *configv1.ClusterVersion | ||
| var restoreChannel, restoreUpstream bool | ||
| var caBundleFilePath string | ||
|
|
||
| g.BeforeAll(func() { | ||
| isMicroShift, err := exutil.IsMicroShiftCluster(oc.AdminKubeClient()) | ||
|
|
@@ -51,10 +53,14 @@ var _ = g.Describe("[Serial][sig-cli] oc adm upgrade recommend", g.Ordered, func | |
| if restoreUpstream { | ||
| oc.Run("patch", "clusterversions.config.openshift.io", "version", "--type", "json", "-p", fmt.Sprintf(`[{"op": "add", "path": "/spec/upstream", "value": "%s"}]`, cv.Spec.Upstream)).Execute() | ||
| } | ||
|
|
||
| if caBundleFilePath != "" { | ||
| os.Remove(caBundleFilePath) | ||
| } | ||
| }) | ||
|
|
||
| g.It("runs successfully, even without upstream OpenShift Update Service customization", func() { | ||
| _, err := oc.Run("adm", "upgrade", "recommend").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND", "true").Output() | ||
| _, err := oc.Run("adm", "upgrade", "recommend").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND", "true").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND_PRECHECK", "true").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND_ACCEPT", "true").Output() | ||
| o.Expect(err).NotTo(o.HaveOccurred()) | ||
| }) | ||
|
|
||
|
|
@@ -65,7 +71,7 @@ var _ = g.Describe("[Serial][sig-cli] oc adm upgrade recommend", g.Ordered, func | |
| } | ||
| restoreChannel = true | ||
|
|
||
| out, err := oc.Run("adm", "upgrade", "recommend").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND", "true").Output() | ||
| out, err := oc.Run("adm", "upgrade", "recommend").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND", "true").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND_PRECHECK", "true").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND_ACCEPT", "true").Output() | ||
| o.Expect(err).NotTo(o.HaveOccurred()) | ||
| err = matchRegexp(out, `.*The update channel has not been configured.*`) | ||
| o.Expect(err).NotTo(o.HaveOccurred()) | ||
|
|
@@ -99,7 +105,7 @@ var _ = g.Describe("[Serial][sig-cli] oc adm upgrade recommend", g.Ordered, func | |
| }) | ||
|
|
||
| g.It("runs successfully", func() { | ||
| out, err := oc.Run("adm", "upgrade", "recommend").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND", "true").Output() | ||
| out, err := oc.Run("adm", "upgrade", "recommend").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND", "true").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND_PRECHECK", "true").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND_ACCEPT", "true").Output() | ||
| o.Expect(err).NotTo(o.HaveOccurred()) | ||
| err = matchRegexp(out, `.*Upstream update service: http://.* | ||
| Channel: test-channel [(]available channels: other-channel, test-channel[)] | ||
|
|
@@ -110,6 +116,7 @@ No updates available. You may still upgrade to a specific release image.*`) | |
|
|
||
| g.Context("When the update service has conditional recommendations", func() { | ||
| var currentVersion *semver.Version | ||
| var token string | ||
|
|
||
| g.BeforeAll(func() { | ||
| isHyperShift, err := exutil.IsHypershift(ctx, oc.AdminConfigClient()) | ||
|
|
@@ -175,16 +182,45 @@ No updates available. You may still upgrade to a specific release image.*`) | |
| } | ||
| restoreUpstream = true | ||
|
|
||
| defaultIngressCert, err := getDefaultIngressCertificate(ctx, oc) | ||
| o.Expect(err).NotTo(o.HaveOccurred()) | ||
|
|
||
| kubeCerts, err := getKubernetesAPIServerCertificates(ctx, oc) | ||
| o.Expect(err).NotTo(o.HaveOccurred()) | ||
|
|
||
| caBundleFile, err := os.CreateTemp("", "ca-bundle") | ||
| caBundleFilePath = caBundleFile.Name() | ||
| _, err = caBundleFile.WriteString(fmt.Sprintf("%s\n%s", defaultIngressCert, kubeCerts)) | ||
| o.Expect(err).NotTo(o.HaveOccurred()) | ||
|
|
||
| // alert retrieval requires a token-based kubeconfig to avoid: | ||
| // Failed to check for at least some preconditions: failed to get alerts from Thanos: no token is currently in use for this session | ||
| o.Expect(oc.Run("create").Args("serviceaccount", "test").Execute()).To(o.Succeed()) | ||
| o.Expect(oc.Run("create").Args("clusterrolebinding", fmt.Sprintf("%s-test", oc.Namespace()), "--clusterrole=cluster-admin", fmt.Sprintf("--serviceaccount=%s:test", oc.Namespace())).Execute()).To(o.Succeed()) | ||
| token, err = oc.Run("create").Args("token", "test").Output() | ||
| o.Expect(err).NotTo(o.HaveOccurred()) | ||
|
|
||
| time.Sleep(16 * time.Second) // Give the CVO time to retrieve recommendations and push to status | ||
| }) | ||
|
|
||
| g.AfterAll(func() { | ||
| // apparently ClusterRoleBindings are not automatically garbage-collected after the referenced service-account is removed (as part of namespace removal). | ||
| oc.Run("delete").Args("clusterrolebinding", fmt.Sprintf("%s-test", oc.Namespace())).Execute() | ||
| }) | ||
|
|
||
| g.It("runs successfully when listing all updates", func() { | ||
| out, err := oc.Run("adm", "upgrade", "recommend").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND", "true").Output() | ||
| o.Expect(err).NotTo(o.HaveOccurred()) | ||
| err = matchRegexp(out, `Upstream update service: http://.* | ||
| oc.WithKubeConfigCopy(func(oc *exutil.CLI) { | ||
| o.Expect(oc.Run("config", "set-credentials").Args("test", "--token", token).Execute()).To(o.Succeed()) | ||
| o.Expect(oc.Run("config", "set-context").Args("--current", "--user", "test").Execute()).To(o.Succeed()) | ||
|
|
||
| out, err := oc.Run("--certificate-authority", caBundleFilePath, "adm", "upgrade", "recommend").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND", "true").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND_PRECHECK", "true").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND_ACCEPT", "true").Output() | ||
| o.Expect(err).NotTo(o.HaveOccurred()) | ||
| err = matchRegexp(out, `The following conditions found no cause for concern in updating this cluster to later releases.* | ||
|
|
||
| Upstream update service: http://.* | ||
| Channel: test-channel [(]available channels: other-channel, test-channel[)] | ||
|
|
||
| Updates to 4.[0-9]*: | ||
| Updates to 4[.][0-9]*: | ||
|
|
||
| Version: 4[.][0-9]*[.]0 | ||
| Image: example[.]com/test@sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
|
|
@@ -195,21 +231,31 @@ Updates to 4[.][0-9]*: | |
| VERSION *ISSUES | ||
| 4[.][0-9]*[.]999 *no known issues relevant to this cluster | ||
| 4[.][0-9]*[.]998 *no known issues relevant to this cluster`) | ||
| o.Expect(err).NotTo(o.HaveOccurred()) | ||
| o.Expect(err).NotTo(o.HaveOccurred()) | ||
| }) | ||
| }) | ||
|
|
||
| g.It("runs successfully with conditional recommendations to the --version target", func() { | ||
| out, err := oc.Run("adm", "upgrade", "recommend", "--version", fmt.Sprintf("4.%d.0", currentVersion.Minor+1)).EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND", "true").Output() | ||
| o.Expect(err).NotTo(o.HaveOccurred()) | ||
| err = matchRegexp(out, `Upstream update service: http://.* | ||
| oc.WithKubeConfigCopy(func(oc *exutil.CLI) { | ||
| o.Expect(oc.Run("config", "set-credentials").Args("test", "--token", token).Execute()).To(o.Succeed()) | ||
| o.Expect(oc.Run("config", "set-context").Args("--current", "--user", "test").Execute()).To(o.Succeed()) | ||
|
|
||
| out, err := oc.Run("--certificate-authority", caBundleFilePath, "adm", "upgrade", "recommend", "--version", fmt.Sprintf("4.%d.0", currentVersion.Minor+1), "--accept", "ConditionalUpdateRisk,Failing").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND", "true").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND_PRECHECK", "true").EnvVar("OC_ENABLE_CMD_UPGRADE_RECOMMEND_ACCEPT", "true").Output() | ||
|
|
||
| o.Expect(err).NotTo(o.HaveOccurred()) | ||
| err = matchRegexp(out, `The following conditions found no cause for concern in updating this cluster to later releases.* | ||
|
|
||
| Upstream update service: http://.* | ||
| Channel: test-channel [(]available channels: other-channel, test-channel[)] | ||
|
|
||
| Update to 4[.][0-9]*[.]0 Recommended=False: | ||
| Image: example.com/test@sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| Release URL: https://example.com/release/4[.][0-9]*[.]0 | ||
| Reason: (TestRiskA|MultipleReasons) | ||
| Message: (?s:.*)This is a test risk. https://example.com/testRiskA`) | ||
| o.Expect(err).NotTo(o.HaveOccurred()) | ||
| Reason: accepted (TestRiskA|MultipleReasons) via ConditionalUpdateRisk | ||
| Message: (?s:.*)This is a test risk[.] https://example.com/testRiskA | ||
| Update to 4[.][0-9]*[.]0 has no known issues relevant to this cluster other than the accepted ConditionalUpdateRisk(|,Failing).`) | ||
| o.Expect(err).NotTo(o.HaveOccurred()) | ||
| }) | ||
| }) | ||
| }) | ||
| }) | ||
|
|
@@ -291,3 +337,43 @@ python3 -m http.server --bind :: | |
| Path: "graph", | ||
| }, nil | ||
| } | ||
|
|
||
| func getDefaultIngressCertificate(ctx context.Context, oc *exutil.CLI) (string, error) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is amazing! |
||
| defaultIngressSecretName, err := oc.Run("get").Args("--namespace=openshift-ingress-operator", "-o", "jsonpath={.spec.defaultCertificate.name}", "ingresscontroller.operator.openshift.io", "default").Output() | ||
| if err != nil { | ||
| return "", err | ||
| } | ||
|
|
||
| if defaultIngressSecretName == "" { | ||
| defaultIngressSecretName = "router-certs-default" | ||
| } | ||
|
|
||
| ingressNamespace := "openshift-ingress" | ||
| defaultIngressCert, err := oc.Run("extract").Args("--namespace", ingressNamespace, fmt.Sprintf("secret/%s", defaultIngressSecretName), "--keys=tls.crt", "--to=-").Output() | ||
| if err != nil { | ||
| return "", err | ||
| } | ||
|
Comment on lines
+342
to
+355
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hehe given my push for "let's stop using
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. they don't need to be |
||
| defaultIngressCert = fmt.Sprintf("%s\n", defaultIngressCert) // ensure a trailing newline, even if the earlier Output() stripped trailing newlines | ||
| framework.Logf("default ingress certificate from the %s secret in the %s namespace: %q", defaultIngressSecretName, ingressNamespace, fmt.Sprintf("%s...", defaultIngressCert[:30])) | ||
| return defaultIngressCert, nil | ||
| } | ||
|
|
||
| func getKubernetesAPIServerCertificates(ctx context.Context, oc *exutil.CLI) (string, error) { | ||
| kubeNamespace := "openshift-kube-apiserver" | ||
| secrets, err := oc.AdminKubeClient().CoreV1().Secrets(kubeNamespace).List(ctx, metav1.ListOptions{}) | ||
| if err != nil { | ||
| return "", err | ||
| } | ||
|
|
||
| certs := make([]string, 0, len(secrets.Items)) | ||
| for _, secret := range secrets.Items { | ||
| if secret.Type != corev1.SecretTypeTLS { | ||
| continue | ||
| } | ||
| certs = append(certs, string(secret.Data["tls.crt"])) | ||
| } | ||
|
|
||
| kubeCerts := strings.Join(certs, "") | ||
| framework.Logf("default Kubernetes certificates from TLS secrets in the %s namespace: %q", kubeNamespace, fmt.Sprintf("%s...", kubeCerts[:30])) | ||
| return kubeCerts, nil | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hrm,
e2e-aws-ovn-single-node-serialfailed:The test-case that covers auth availability flaked:
Working in an exception might be tricky regular-expression handling. Trying to gauge how frequent this issue is:
/payload-aggregate periodic-ci-openshift-release-master-nightly-4.21-e2e-aws-ovn-single-node-serial 20
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of the aggregation run's 20 attempts:
--versiontest-case onauthenticationAvailable=False.prometheus-operatorwatch requests.context deadline exceededout ofrunUpdateService, withFailed to pull image...authentication requiredissues trying to get thetoolsimage.authenticationAvailable=False(OAuthServerDeployment_NoPod).So the auth functionality is pretty flaky in these single-node clusters under serial-suite load. I've pushed c68be5e -> 78ac50f, to hopefully soften this test-case enough to not trip over this issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With 78ac50f in place, the only serial presubmit which failed was e2e-metal-ipi-serial-2of2, on an unrelated metrics-auth
context deadline exceededissue. The 20 single-node runs are still not great, but no longer has any failures related to my test-cases:TestImageStreamTagsAdmissiontest-case.prometheus-operatorwatch requests.ingressClusterOperator goingAvailable=False.