diff --git a/test/extended/clusterversion/OWNERS b/test/extended/clusterversion/OWNERS new file mode 100644 index 000000000000..4ab021ebf3bb --- /dev/null +++ b/test/extended/clusterversion/OWNERS @@ -0,0 +1,5 @@ +reviewers: + - cluster-version-operator-test-case-reviewers + - Prashanth684 +approvers: + - cluster-version-operator-test-case-approvers diff --git a/test/extended/clusterversion/clusterversion.go b/test/extended/clusterversion/clusterversion.go new file mode 100644 index 000000000000..668231986640 --- /dev/null +++ b/test/extended/clusterversion/clusterversion.go @@ -0,0 +1,53 @@ +package clusterversion + +import ( + "context" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + g "github.com/onsi/ginkgo/v2" + o "github.com/onsi/gomega" + configv1 "github.com/openshift/api/config/v1" + configclient "github.com/openshift/client-go/config/clientset/versioned" + exutil "github.com/openshift/origin/test/extended/util" +) + +// The desired architecture field was introduced as part of a feature that provides a toggle for an imagestream's importMode: https://github.com/openshift/api/pull/2024 +var _ = g.Describe("[sig-cluster-lifecycle][OCPFeatureGate:ImageStreamImportMode] ClusterVersion API", func() { + defer g.GinkgoRecover() + oc := exutil.NewCLIWithoutNamespace("") + + g.It("desired architecture should be valid when architecture is set in release payload metadata [apigroup:config.openshift.io]", func() { + TestClusterVersionDesiredArchitecture(g.GinkgoT(), oc) + }) + +}) + +func TestClusterVersionDesiredArchitecture(t g.GinkgoTInterface, oc *exutil.CLI) { + ctx := context.Background() + + archMetadata, _, err := oc.AsAdmin().Run("adm", "release", "info", `-ojsonpath={.metadata.metadata.release\.openshift\.io\/architecture}`).Outputs() + if err != nil { + cleanup, cmdArgs, err := exutil.PrepareImagePullSecretAndCABundle(oc) + if cleanup != nil { + defer cleanup() + } + o.Expect(err).NotTo(o.HaveOccurred()) + archMetadata, _, err = oc.AsAdmin().Run("adm", "release", "info", `-ojsonpath={.metadata.metadata.release\.openshift\.io\/architecture}`).Args(cmdArgs...).Outputs() + o.Expect(err).NotTo(o.HaveOccurred()) + } else { + o.Expect(err).NotTo(o.HaveOccurred()) + } + + // Check desired.Architecture in the CV + configClient, err := configclient.NewForConfig(oc.AdminConfig()) + o.Expect(err).NotTo(o.HaveOccurred()) + clusterVersion, err := configClient.ConfigV1().ClusterVersions().Get(ctx, "version", metav1.GetOptions{}) + o.Expect(err).NotTo(o.HaveOccurred()) + + if archMetadata == "multi" { + o.Expect(clusterVersion.Status.Desired.Architecture).To(o.Equal(configv1.ClusterVersionArchitectureMulti)) + } else { + o.Expect(clusterVersion.Status.Desired.Architecture).To(o.BeEmpty()) + } +} diff --git a/test/extended/include.go b/test/extended/include.go index 79dc851d5af9..0bfae962edc8 100644 --- a/test/extended/include.go +++ b/test/extended/include.go @@ -19,6 +19,7 @@ import ( _ "github.com/openshift/origin/test/extended/cli" _ "github.com/openshift/origin/test/extended/cloud_controller_manager" _ "github.com/openshift/origin/test/extended/cluster" + _ "github.com/openshift/origin/test/extended/clusterversion" _ "github.com/openshift/origin/test/extended/cmd" _ "github.com/openshift/origin/test/extended/controller_manager" _ "github.com/openshift/origin/test/extended/coreos" diff --git a/test/extended/util/annotate/generated/zz_generated.annotations.go b/test/extended/util/annotate/generated/zz_generated.annotations.go index 88843956372d..7a6567d9c7d5 100644 --- a/test/extended/util/annotate/generated/zz_generated.annotations.go +++ b/test/extended/util/annotate/generated/zz_generated.annotations.go @@ -1033,6 +1033,8 @@ var Annotations = map[string]string{ "[sig-cluster-lifecycle][Feature:Machines][Serial] Managed cluster should grow and decrease when scaling different machineSets simultaneously [Timeout:30m][apigroup:machine.openshift.io]": " [Suite:openshift/conformance/serial]", + "[sig-cluster-lifecycle][OCPFeatureGate:ImageStreamImportMode] ClusterVersion API desired architecture should be valid when architecture is set in release payload metadata [apigroup:config.openshift.io]": " [Suite:openshift/conformance/parallel]", + "[sig-coreos] [Conformance] CoreOS bootimages TestBootimagesPresent [apigroup:machineconfiguration.openshift.io]": " [Suite:openshift/conformance/parallel/minimal]", "[sig-devex] check registry.redhat.io is available and samples operator can import sample imagestreams run sample related validations [apigroup:config.openshift.io][apigroup:image.openshift.io]": " [Skipped:Disconnected] [Suite:openshift/conformance/parallel]", diff --git a/test/extended/util/clusterversion.go b/test/extended/util/clusterversion.go index d2061bc2cc83..8c190979f4fd 100644 --- a/test/extended/util/clusterversion.go +++ b/test/extended/util/clusterversion.go @@ -4,8 +4,11 @@ import ( "context" "encoding/json" "fmt" + "io/ioutil" + "os" corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" restclient "k8s.io/client-go/rest" "k8s.io/kubernetes/test/e2e/framework" @@ -113,3 +116,66 @@ func DetermineImageFromRelease(ctx context.Context, oc *CLI, imageTagName string } return "", fmt.Errorf("Could not find image: %s", imageTagName) } + +// prepareImagePullSecretAndCABundle prepares the image pull secret and optional user CA bundle for use, +// returning the necessary command-line arguments, or an error if setup fails. +func PrepareImagePullSecretAndCABundle(oc *CLI) (func(), []string, error) { + kubeClient := oc.AdminKubeClient() + // Try to use the same pull secret as the cluster under test + imagePullSecret, err := kubeClient.CoreV1().Secrets("openshift-config").Get(context.Background(), "pull-secret", metav1.GetOptions{}) + if err != nil { + return nil, nil, fmt.Errorf("unable to get pull secret from cluster: %v", err) + } + + // cache file to local temp location + imagePullFile, err := ioutil.TempFile("", "image-pull-secret") + if err != nil { + return nil, nil, fmt.Errorf("unable to create a temporary file: %v", err) + } + cleanup := func() { + os.Remove(imagePullFile.Name()) + } + + // write the content + imagePullSecretBytes := imagePullSecret.Data[".dockerconfigjson"] + if _, err = imagePullFile.Write(imagePullSecretBytes); err != nil { + return cleanup, nil, fmt.Errorf("unable to write pull secret to temp file: %v", err) + } + if err = imagePullFile.Close(); err != nil { + return cleanup, nil, fmt.Errorf("unable to close file: %v", err) + } + + cmdArgs := []string{"--registry-config", imagePullFile.Name()} + + // Trust also user trusted CA from the cluster under test + userCaBundle, err := kubeClient.CoreV1().ConfigMaps("openshift-config").Get(context.Background(), "user-ca-bundle", metav1.GetOptions{}) + if err != nil { + if !apierrors.IsNotFound(err) { + return cleanup, nil, fmt.Errorf("unable to get user-ca-bundle configmap from cluster: %v", err) + } + } + + if userCaBundle != nil { + // cache file to local temp location + userCaBundleFile, err := ioutil.TempFile("", "user-ca-bundle") + if err != nil { + return cleanup, nil, fmt.Errorf("unable to create a temporary file: %v", err) + } + + cleanup = func() { + os.Remove(imagePullFile.Name()) + os.Remove(userCaBundleFile.Name()) + } + + // write the content + userCaBundleString := userCaBundle.Data["ca-bundle.crt"] + if _, err = userCaBundleFile.WriteString(userCaBundleString); err != nil { + return cleanup, nil, fmt.Errorf("unable to write user CA bundle to temp file: %v", err) + } + if err = userCaBundleFile.Close(); err != nil { + return cleanup, nil, fmt.Errorf("unable to close file: %v", err) + } + cmdArgs = append(cmdArgs, "--certificate-authority", userCaBundleFile.Name()) + } + return cleanup, cmdArgs, nil +} diff --git a/zz_generated.manifests/test-reporting.yaml b/zz_generated.manifests/test-reporting.yaml index b401602b3a5e..d0052618a136 100644 --- a/zz_generated.manifests/test-reporting.yaml +++ b/zz_generated.manifests/test-reporting.yaml @@ -148,6 +148,9 @@ spec: mock driver Static provisioning should honor pv retain reclaim policy' - featureGate: ImageStreamImportMode tests: + - testName: '[sig-cluster-lifecycle][OCPFeatureGate:ImageStreamImportMode] ClusterVersion + API desired architecture should be valid when architecture is set in release + payload metadata [apigroup:config.openshift.io]' - testName: '[sig-imageregistry][OCPFeatureGate:ImageStreamImportMode][Serial] ImageStream API import mode should be Legacy if the import mode specified in image.config.openshift.io config is Legacy [apigroup:image.openshift.io]'