55 "fmt"
66 "net"
77 "net/url"
8+ "os"
89 "strconv"
910 "strings"
1011 "text/template"
@@ -31,6 +32,7 @@ var _ = g.Describe("[Serial][sig-cli] oc adm upgrade recommend", g.Ordered, func
3132 oc := exutil .NewCLIWithFramework (f ).AsAdmin ()
3233 var cv * configv1.ClusterVersion
3334 var restoreChannel , restoreUpstream bool
35+ var caBundleFilePath string
3436
3537 g .BeforeAll (func () {
3638 isMicroShift , err := exutil .IsMicroShiftCluster (oc .AdminKubeClient ())
@@ -51,6 +53,10 @@ var _ = g.Describe("[Serial][sig-cli] oc adm upgrade recommend", g.Ordered, func
5153 if restoreUpstream {
5254 oc .Run ("patch" , "clusterversions.config.openshift.io" , "version" , "--type" , "json" , "-p" , fmt .Sprintf (`[{"op": "add", "path": "/spec/upstream", "value": "%s"}]` , cv .Spec .Upstream )).Execute ()
5355 }
56+
57+ if caBundleFilePath != "" {
58+ os .Remove (caBundleFilePath )
59+ }
5460 })
5561
5662 g .It ("runs successfully, even without upstream OpenShift Update Service customization" , func () {
@@ -110,6 +116,7 @@ No updates available. You may still upgrade to a specific release image.*`)
110116
111117 g .Context ("When the update service has conditional recommendations" , func () {
112118 var currentVersion * semver.Version
119+ var token string
113120
114121 g .BeforeAll (func () {
115122 isHyperShift , err := exutil .IsHypershift (ctx , oc .AdminConfigClient ())
@@ -175,15 +182,38 @@ No updates available. You may still upgrade to a specific release image.*`)
175182 }
176183 restoreUpstream = true
177184
185+ defaultIngressCert , err := getDefaultIngressCertificate (ctx , oc )
186+ o .Expect (err ).NotTo (o .HaveOccurred ())
187+
188+ kubeCerts , err := getKubernetesAPIServerCertificates (ctx , oc )
189+ o .Expect (err ).NotTo (o .HaveOccurred ())
190+
191+ caBundleFile , err := os .CreateTemp ("" , "ca-bundle" )
192+ caBundleFilePath = caBundleFile .Name ()
193+ _ , err = caBundleFile .WriteString (fmt .Sprintf ("%s\n %s" , defaultIngressCert , kubeCerts ))
194+ o .Expect (err ).NotTo (o .HaveOccurred ())
195+
196+ // alert retrieval requires a token-based kubeconfig to avoid:
197+ // Failed to check for at least some preconditions: failed to get alerts from Thanos: no token is currently in use for this session
198+ o .Expect (oc .Run ("create" ).Args ("serviceaccount" , "test" ).Execute ()).To (o .Succeed ())
199+ o .Expect (oc .Run ("create" ).Args ("clusterrolebinding" , "test" , "--clusterrole=cluster-admin" , fmt .Sprintf ("--serviceaccount=%s:test" , oc .Namespace ())).Execute ()).To (o .Succeed ())
200+ token , err = oc .Run ("create" ).Args ("token" , "test" ).Output ()
201+ o .Expect (err ).NotTo (o .HaveOccurred ())
202+
178203 time .Sleep (16 * time .Second ) // Give the CVO time to retrieve recommendations and push to status
179204 })
180205
181206 g .It ("runs successfully when listing all updates" , func () {
182- 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 ()
183- o .Expect (err ).NotTo (o .HaveOccurred ())
184- err = matchRegexp (out , `Upstream update service: http://.*
185- Channel: test-channel [(]available channels: other-channel, test-channel[)]
207+ oc .WithKubeConfigCopy (func (oc * exutil.CLI ) {
208+ o .Expect (oc .Run ("config" , "set-credentials" ).Args ("test" , "--token" , token ).Execute ()).To (o .Succeed ())
209+ o .Expect (oc .Run ("config" , "set-context" ).Args ("--current" , "--user" , "test" ).Execute ()).To (o .Succeed ())
186210
211+ 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 ()
212+ o .Expect (err ).NotTo (o .HaveOccurred ())
213+ err = matchRegexp (out , `The following conditions found no cause for concern in updating this cluster to later releases.*
214+
215+ Upstream update service: http://.*
216+ Channel: test-channel [(]available channels: other-channel, test-channel[)]
187217Updates to 4.[0-9]*:
188218
189219 Version: 4[.][0-9]*[.]0
@@ -195,22 +225,16 @@ Updates to 4[.][0-9]*:
195225 VERSION *ISSUES
196226 4[.][0-9]*[.]999 *no known issues relevant to this cluster
197227 4[.][0-9]*[.]998 *no known issues relevant to this cluster` )
198- o .Expect (err ).NotTo (o .HaveOccurred ())
228+ o .Expect (err ).NotTo (o .HaveOccurred ())
229+ })
199230 })
200231
201232 g .It ("runs successfully with an accepted conditional recommendation to the --version target" , func () {
202- // alert retrieval requires a token-based kubeconfig to avoid:
203- // Failed to check for at least some preconditions: failed to get alerts from Thanos: no token is currently in use for this session
204- o .Expect (oc .Run ("create" ).Args ("serviceaccount" , "test" ).Execute ()).To (o .Succeed ())
205- o .Expect (oc .Run ("create" ).Args ("clusterrolebinding" , "test" , "--clusterrole=cluster-admin" , fmt .Sprintf ("--serviceaccount=%s:test" , oc .Namespace ())).Execute ()).To (o .Succeed ())
206- token , err := oc .Run ("create" ).Args ("token" , "test" ).Output ()
207- o .Expect (err ).NotTo (o .HaveOccurred ())
208-
209233 oc .WithKubeConfigCopy (func (oc * exutil.CLI ) {
210234 o .Expect (oc .Run ("config" , "set-credentials" ).Args ("test" , "--token" , token ).Execute ()).To (o .Succeed ())
211235 o .Expect (oc .Run ("config" , "set-context" ).Args ("--current" , "--user" , "test" ).Execute ()).To (o .Succeed ())
212236
213- out , err := oc .Run ("adm" , "upgrade" , "recommend" , "--version" , fmt .Sprintf ("4.%d.0" , currentVersion .Minor + 1 ), "--accept" , "ConditionalUpdateRisk" ).EnvVar ("OC_ENABLE_CMD_UPGRADE_RECOMMEND" , "true" ).EnvVar ("OC_ENABLE_CMD_UPGRADE_RECOMMEND_PRECHECK" , "true" ).EnvVar ("OC_ENABLE_CMD_UPGRADE_RECOMMEND_ACCEPT" , "true" ).Output ()
237+ out , err := oc .Run ("--certificate-authority" , caBundleFilePath , " adm" , "upgrade" , "recommend" , "--version" , fmt .Sprintf ("4.%d.0" , currentVersion .Minor + 1 ), "--accept" , "ConditionalUpdateRisk" ).EnvVar ("OC_ENABLE_CMD_UPGRADE_RECOMMEND" , "true" ).EnvVar ("OC_ENABLE_CMD_UPGRADE_RECOMMEND_PRECHECK" , "true" ).EnvVar ("OC_ENABLE_CMD_UPGRADE_RECOMMEND_ACCEPT" , "true" ).Output ()
214238 o .Expect (err ).To (o .HaveOccurred ())
215239 err = matchRegexp (out , `The following conditions found no cause for concern in updating this cluster to later releases.*
216240
@@ -305,3 +329,43 @@ python3 -m http.server --bind ::
305329 Path : "graph" ,
306330 }, nil
307331}
332+
333+ func getDefaultIngressCertificate (ctx context.Context , oc * exutil.CLI ) (string , error ) {
334+ defaultIngressSecretName , err := oc .Run ("get" ).Args ("--namespace=openshift-ingress-operator" , "-o" , "jsonpath={.spec.defaultCertificate.name}" , "ingresscontroller.operator.openshift.io" , "default" ).Output ()
335+ if err != nil {
336+ return "" , err
337+ }
338+
339+ if defaultIngressSecretName == "" {
340+ defaultIngressSecretName = "router-certs-default"
341+ }
342+
343+ ingressNamespace := "openshift-ingress"
344+ defaultIngressCert , err := oc .Run ("extract" ).Args ("--namespace" , ingressNamespace , fmt .Sprintf ("secret/%s" , defaultIngressSecretName ), "--keys=tls.crt" , "--to=-" ).Output ()
345+ if err != nil {
346+ return "" , err
347+ }
348+ defaultIngressCert = fmt .Sprintf ("%s\n " , defaultIngressCert ) // ensure a trailing newline, even if the earlier Output() stripped trailing newlines
349+ framework .Logf ("default ingress certificate from the %s secret in the %s namespace: %q" , defaultIngressSecretName , ingressNamespace , defaultIngressCert )
350+ return defaultIngressCert , nil
351+ }
352+
353+ func getKubernetesAPIServerCertificates (ctx context.Context , oc * exutil.CLI ) (string , error ) {
354+ kubeNamespace := "openshift-kube-apiserver"
355+ secrets , err := oc .AdminKubeClient ().CoreV1 ().Secrets (kubeNamespace ).List (ctx , metav1.ListOptions {})
356+ if err != nil {
357+ return "" , err
358+ }
359+
360+ certs := make ([]string , 0 , len (secrets .Items ))
361+ for _ , secret := range secrets .Items {
362+ if secret .Type != corev1 .SecretTypeTLS {
363+ continue
364+ }
365+ certs = append (certs , string (secret .Data ["tls.crt" ]))
366+ }
367+
368+ kubeCerts := strings .Join (certs , "" )
369+ framework .Logf ("default Kubernetes certificates from TLS secrets in the %s namespace: %q" , kubeNamespace , kubeCerts )
370+ return kubeCerts , nil
371+ }
0 commit comments