From fd0b89d9a2c604fb05a1543dd63a0b4cefc2b94a Mon Sep 17 00:00:00 2001 From: Elena German Date: Mon, 17 Jun 2024 15:30:23 -0400 Subject: [PATCH 1/5] bump vendors --- go.mod | 4 +- go.sum | 4 +- .../internal/cleanup/namespace.go | 49 +++ .../internal/vcorecommon/keda-validation.go | 217 +++++++++++ .../eco-goinfra/pkg/keda/kedacontroller.go | 316 ++++++++++++++++ .../eco-goinfra/pkg/keda/scaleobject.go | 358 ++++++++++++++++++ .../pkg/keda/triggerauthentication.go | 279 ++++++++++++++ .../openshift-kni/eco-goinfra/pkg/pod/pod.go | 25 ++ vendor/modules.txt | 3 +- 9 files changed, 1250 insertions(+), 5 deletions(-) create mode 100644 tests/system-tests/internal/cleanup/namespace.go create mode 100644 tests/system-tests/vcore/internal/vcorecommon/keda-validation.go create mode 100644 vendor/github.com/openshift-kni/eco-goinfra/pkg/keda/kedacontroller.go create mode 100644 vendor/github.com/openshift-kni/eco-goinfra/pkg/keda/scaleobject.go create mode 100644 vendor/github.com/openshift-kni/eco-goinfra/pkg/keda/triggerauthentication.go diff --git a/go.mod b/go.mod index 3ed39da59..e2b403b82 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/nmstate/kubernetes-nmstate/api v0.0.0-20240605150941-df565dd7bf35 github.com/onsi/ginkgo/v2 v2.19.0 github.com/onsi/gomega v1.33.1 - github.com/openshift-kni/eco-goinfra v0.0.0-20240620154035-1f702e37c052 // release-4.15 + github.com/openshift-kni/eco-goinfra v0.0.0-20240621192821-7c55fda74f32 // release-4.15 github.com/openshift-kni/k8sreporter v1.0.5 github.com/openshift/api v3.9.1-0.20191111211345-a27ff30ebf09+incompatible github.com/openshift/assisted-service/api v0.0.0 @@ -41,6 +41,7 @@ require ( ) require ( + github.com/kedacore/keda-olm-operator v0.0.0-20240501182040-762f6be5a942 github.com/openshift-kni/lifecycle-agent v0.0.0-20240606123201-0c45cd13c2f1 github.com/openshift/client-go v0.0.1 github.com/openshift/installer v0.0.0-00010101000000-000000000000 @@ -63,7 +64,6 @@ require ( github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 // indirect github.com/gorilla/websocket v1.5.1 // indirect github.com/kdomanski/iso9660 v0.2.1 // indirect - github.com/kedacore/keda-olm-operator v0.0.0-20240501182040-762f6be5a942 // indirect github.com/kedacore/keda/v2 v2.14.0 // indirect github.com/lib/pq v1.10.9 // indirect github.com/metal3-io/baremetal-operator/pkg/hardwareutils v0.5.1 // indirect diff --git a/go.sum b/go.sum index 03d2902ae..5b5e594bd 100644 --- a/go.sum +++ b/go.sum @@ -1691,8 +1691,8 @@ github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/openshift-kni/cluster-group-upgrades-operator v0.0.0-20240423171335-f07cdbf8af2c h1:wAPCXsnAXOUAJ5DYlVgGUcV9YBSiVlH4o9tbQ9py8ZY= github.com/openshift-kni/cluster-group-upgrades-operator v0.0.0-20240423171335-f07cdbf8af2c/go.mod h1:hkzqKpmQvh7vgPx8Hw6IExJorKPM0dEeJdOXjIW3gNw= -github.com/openshift-kni/eco-goinfra v0.0.0-20240620154035-1f702e37c052 h1:OHLKRTDEtuRkHeUmmKFRcJkVDQ4JdNsBsJGfqs7Ix1Q= -github.com/openshift-kni/eco-goinfra v0.0.0-20240620154035-1f702e37c052/go.mod h1:oGFnQMzZ/bqtnjdh9Rx44NzsMGWaZXgyQsoS0Q7faJ8= +github.com/openshift-kni/eco-goinfra v0.0.0-20240621192821-7c55fda74f32 h1:mLsBeu1cSEvCbJ2hEGDqoMA46leC6FD+V0zPLczkEVQ= +github.com/openshift-kni/eco-goinfra v0.0.0-20240621192821-7c55fda74f32/go.mod h1:oGFnQMzZ/bqtnjdh9Rx44NzsMGWaZXgyQsoS0Q7faJ8= github.com/openshift-kni/k8sreporter v1.0.5 h1:1GYBc/BTZyVoXilHef43v9A8BSzw700zAPZ6zsZvo6Y= github.com/openshift-kni/k8sreporter v1.0.5/go.mod h1:fg8HI9yxiKAi6UzR6NTtrmQmA2WKzUqmkRUHwQ1+Bj8= github.com/openshift-kni/lifecycle-agent v0.0.0-20240606123201-0c45cd13c2f1 h1:y+0Ecc+MSZA/GNS3VOpKq+XK9x8qoNA7TlyHvqbVbpw= diff --git a/tests/system-tests/internal/cleanup/namespace.go b/tests/system-tests/internal/cleanup/namespace.go new file mode 100644 index 000000000..55463b2a9 --- /dev/null +++ b/tests/system-tests/internal/cleanup/namespace.go @@ -0,0 +1,49 @@ +package cleanup + +import ( + "fmt" + "github.com/golang/glog" + "github.com/openshift-kni/eco-goinfra/pkg/clients" + "github.com/openshift-kni/eco-goinfra/pkg/deployment" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "time" +) + +// CleanupNamespace cleanup specific namespace and delete it according to the flag config. +func CleanupNamespace(apiClient *clients.Settings, nsname string, toDelete bool, timeout time.Duration) error { + glog.V(100).Infof("Scaling down namespace %s resources", nsname) + + deleteResources := []string{"deployment", "replicaset", "replicationcontroller", "statefulset"} + + deployments, err := deployment.List(apiClient, nsname, metav1.ListOptions{}) + glog.V(100).Infof("Scaling down deployment resources: %v", deployments) + + if err == nil { + for _, depl := range deployments { + depl, deletionErr := depl.WithReplicas(0).Update() + + if deletionErr != nil { + return fmt.Errorf("failed to delete deployment %s in namespace %s", + depl.Definition.Name, depl.Definition.Namespace) + } + } + glog.V(100).Infof("no active deployments found in namespace %s", nsname) + } + + replicaset, err := replicaset.List(apiClient, nsname, metav1.ListOptions{}) + glog.V(100).Infof("Scaling down replicaset resources: %v", replicaset) + + if err == nil { + for _, depl := range deployments { + depl, deletionErr := depl.WithReplicas(0).Update() + + if deletionErr != nil { + return fmt.Errorf("failed to delete deployment %s in namespace %s", + depl.Definition.Name, depl.Definition.Namespace) + } + } + glog.V(100).Infof("no active deployments found in namespace %s", nsname) + } + + return nil +} diff --git a/tests/system-tests/vcore/internal/vcorecommon/keda-validation.go b/tests/system-tests/vcore/internal/vcorecommon/keda-validation.go new file mode 100644 index 000000000..9f5ef3dff --- /dev/null +++ b/tests/system-tests/vcore/internal/vcorecommon/keda-validation.go @@ -0,0 +1,217 @@ +package vcorecommon + +import ( + "fmt" + kedav1alpha1 "github.com/kedacore/keda-olm-operator/apis/keda/v1alpha1" + "github.com/openshift-kni/eco-goinfra/pkg/configmap" + "github.com/openshift-kni/eco-goinfra/pkg/keda" + "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/mirroring" + "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/platform" + "os" + "path/filepath" + "time" + + "github.com/golang/glog" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/apiobjectshelper" + + "github.com/openshift-kni/eco-goinfra/pkg/reportxml" + . "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreinittools" + "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreparams" +) + +const ( + kedaScaleObjectName = "prometheus-scaledobject" + configmapName = "cluster-monitoring-config" + configmapNamespace = "openshift-monitoring" + maxReplicaCount = 8 + testAppServicemonitorName = "keda-testing-sm" + serviceaccountName = "thanos" + triggerAuthName = "keda-trigger-auth-prometheus" + metricsReaderName = "thanos-metrics-reader" + + prometheusOriginMirrorURL = "quay.io/zroubalik" + prometheusImageName = "prometheus-app" + prometheusImageTag = "latest" + + abOriginMirrorURL = "docker.io/jordi" + abImageName = "ab" + abImageTag = "latest" +) + +// VerifyKedaNamespaceExists asserts namespace for NMState operator exists. +func VerifyKedaNamespaceExists(ctx SpecContext) { + err := apiobjectshelper.VerifyNamespaceExists(APIClient, vcoreparams.KedaNamespace, time.Second) + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("Failed to pull %q namespace", vcoreparams.KedaNamespace)) +} // func VerifyKedaNamespaceExists (ctx SpecContext) + +// VerifyKedaDeployment assert that Keda operator deployment succeeded. +func VerifyKedaDeployment(ctx SpecContext) { + err := apiobjectshelper.VerifyOperatorDeployment(APIClient, + vcoreparams.KedaSubscriptionName, + vcoreparams.KedaDeploymentName, + vcoreparams.KedaNamespace, + time.Minute) + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("Keda operator deployment %s failure in the namespace %s; %v", + vcoreparams.KedaDeploymentName, vcoreparams.KedaNamespace, err)) +} // func VerifyKedaDeployment (ctx SpecContext) + +// VerifyKedaControllerDeployment assert that kedaController instance created successfully. +func VerifyKedaControllerDeployment(ctx SpecContext) { + glog.V(vcoreparams.VCoreLogLevel).Infof("Verify kedaController instance exists") + + kedaControllerBuilder := keda.NewKedaControllerBuilder( + APIClient, + vcoreparams.KedaControllerName, + vcoreparams.KedaNamespace) + + if !kedaControllerBuilder.Exists() { + var err error + admissionWebhooks := kedav1alpha1.KedaAdmissionWebhooksSpec{ + LogLevel: "info", + LogEncoder: "console", + } + operator := kedav1alpha1.KedaOperatorSpec{ + LogLevel: "info", + LogEncoder: "console", + } + metricsServer := kedav1alpha1.KedaMetricsServerSpec{ + LogLevel: "0", + } + + kedaControllerBuilder, err = kedaControllerBuilder.WithAdmissionWebhooks(admissionWebhooks). + WithOperator(operator). + WithMetricsServer(metricsServer). + WithWatchNamespace(vcoreparams.KedaWatchNamespace). + Create() + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("Failed to create kedaController instance %q in namespace %q due to: %v", + vcoreparams.KedaControllerName, vcoreparams.KedaNamespace, err.Error())) + Expect(kedaControllerBuilder.Exists()).To(Equal(true), fmt.Sprintf( + "no kedaController instance %s was found in the namespace %s", + vcoreparams.KedaControllerName, vcoreparams.KedaNamespace)) + } +} // func VerifyKedaControllerDeployment (ctx SpecContext) + +// VerifyScaleObjectDeployment assert that scaleObject instance created successfully. +func VerifyScaleObjectDeployment(ctx SpecContext) { + glog.V(vcoreparams.VCoreLogLevel).Info("Verify monitoring status") + var err error + + configMapBuilder := configmap.NewBuilder(APIClient, configmapName, configmapNamespace) + + if !configMapBuilder.Exists() { + configMapBuilder, err = configMapBuilder. + WithData(map[string]string{"config.yaml": "enableUserWorkload: true"}).Create() + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("Failed to create configmap %q in namespace %q due to: %v", + configmapName, configmapNamespace, err.Error())) + Expect(configMapBuilder.Exists()).To(Equal(true), fmt.Sprintf( + "no configmap %s was found in the namespace %s", configmapName, configmapNamespace)) + } + + glog.V(vcoreparams.VCoreLogLevel).Info("Deploy application that exposes Prometheus metrics") + namespace + + glog.V(vcoreparams.VCoreLogLevel).Infof("Verify scaleObject instance deployment and functionality") + + scaleObjectBuilder := keda.NewScaledObjectBuilder(APIClient, kedaScaleObjectName, vcoreparams.KedaWatchNamespace) + if !scaleObjectBuilder.Exists() { + var err error + admissionWebhooks := kedav1alpha1.KedaAdmissionWebhooksSpec{ + LogLevel: "info", + LogEncoder: "console", + } + operator := kedav1alpha1.KedaOperatorSpec{ + LogLevel: "info", + LogEncoder: "console", + } + metricsServer := kedav1alpha1.KedaMetricsServerSpec{ + LogLevel: "0", + } + + scaleObjectBuilder, err = scaleObjectBuilder.WithAdmissionWebhooks(admissionWebhooks). + WithOperator(operator). + WithMetricsServer(metricsServer). + WithWatchNamespace(vcoreparams.KedaWatchNamespace). + Create() + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("Failed to create kedaController instance %q in namespace %q due to: %v", + vcoreparams.KedaControllerName, vcoreparams.KedaNamespace, err.Error())) + Expect(scaleObjectBuilder.Exists()).To(Equal(true), fmt.Sprintf( + "no kedaController instance %s was found in the namespace %s", + vcoreparams.KedaControllerName, vcoreparams.KedaNamespace)) + } +} // func VerifyKedaControllerDeployment (ctx SpecContext) + +// VerifyKedaSuite container that contains tests for Keda verification. +func VerifyKedaSuite() { + Describe( + "Keda validation", + Label(vcoreparams.LabelVCoreOperators), func() { + BeforeAll(func() { + By(fmt.Sprintf("Asserting %s folder exists", vcoreparams.ConfigurationFolderName)) + + homeDir, err := os.UserHomeDir() + Expect(err).To(BeNil(), fmt.Sprint(err)) + + vcoreConfigsFolder := filepath.Join(homeDir, vcoreparams.ConfigurationFolderName) + + glog.V(vcoreparams.VCoreLogLevel).Infof("vcoreConfigsFolder: %s", vcoreConfigsFolder) + + if err := os.Mkdir(vcoreConfigsFolder, 0755); os.IsExist(err) { + glog.V(vcoreparams.VCoreLogLevel).Infof("%s folder already exists", vcoreConfigsFolder) + } + }) + + It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.KedaNamespace), + Label("keda"), VerifyKedaNamespaceExists) + + It("Verifies Keda operator deployment succeeded", + Label("keda"), reportxml.ID("65001"), VerifyKedaDeployment) + + It("Verifies KedaController instance created successfully", + Label("keda"), reportxml.ID("65004"), VerifyKedaControllerDeployment) + + It("Verifies ScaleObject instance created successfully", + Label("keda"), reportxml.ID("65007"), VerifyScaleObjectDeployment) + }) +} + +func getImageUrl(repository, name, tag string) (string, error) { + imageURL := fmt.Sprintf("%s/%s", repository, name) + + isDisconnected, err := platform.IsDisconnectedDeployment(APIClient) + + if err != nil { + return "", err + } + + if !isDisconnected { + glog.V(vcoreparams.VCoreLogLevel).Info("The connected deployment type was detected, " + + "the images mirroring is not required") + } else { + glog.V(vcoreparams.VCoreLogLevel).Infof("Mirror image %s:%s locally", imageURL, tag) + + imageURL, _, err = mirroring.MirrorImageToTheLocalRegistry( + APIClient, + repository, + name, + tag, + VCoreConfig.Host, + VCoreConfig.User, + VCoreConfig.Pass, + VCoreConfig.CombinedPullSecretFile, + VCoreConfig.RegistryRepository) + + if err != nil { + return "", fmt.Errorf("failed to mirror image %s:%s locally due to %v", + imageURL, tag, err) + } + } + + return imageURL, nil +} diff --git a/vendor/github.com/openshift-kni/eco-goinfra/pkg/keda/kedacontroller.go b/vendor/github.com/openshift-kni/eco-goinfra/pkg/keda/kedacontroller.go new file mode 100644 index 000000000..11ba91d70 --- /dev/null +++ b/vendor/github.com/openshift-kni/eco-goinfra/pkg/keda/kedacontroller.go @@ -0,0 +1,316 @@ +package keda + +import ( + "context" + "fmt" + + "github.com/golang/glog" + kedav1alpha1 "github.com/kedacore/keda-olm-operator/apis/keda/v1alpha1" + "github.com/openshift-kni/eco-goinfra/pkg/clients" + "github.com/openshift-kni/eco-goinfra/pkg/msg" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + goclient "sigs.k8s.io/controller-runtime/pkg/client" +) + +// ControllerBuilder provides a struct for KedaController object from the cluster and a KedaController definition. +type ControllerBuilder struct { + // KedaController definition, used to create the KedaController object. + Definition *kedav1alpha1.KedaController + // Created KedaController object. + Object *kedav1alpha1.KedaController + // Used to store latest error message upon defining or mutating KedaController definition. + errorMsg string + // api client to interact with the cluster. + apiClient goclient.Client +} + +// NewControllerBuilder creates a new instance of ControllerBuilder. +func NewControllerBuilder( + apiClient *clients.Settings, name, nsname string) *ControllerBuilder { + glog.V(100).Infof( + "Initializing new kedaController structure with the following params: "+ + "name: %s, namespace: %s", name, nsname) + + if apiClient == nil { + glog.V(100).Infof("kedaController 'apiClient' cannot be empty") + + return nil + } + + builder := &ControllerBuilder{ + apiClient: apiClient.Client, + Definition: &kedav1alpha1.KedaController{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: nsname, + }, + }, + } + + if name == "" { + glog.V(100).Infof("The name of the KedaController is empty") + + builder.errorMsg = "kedaController 'name' cannot be empty" + + return builder + } + + if nsname == "" { + glog.V(100).Infof("The nsname of the KedaController is empty") + + builder.errorMsg = "kedaController 'nsname' cannot be empty" + + return builder + } + + return builder +} + +// PullController pulls existing kedaController from cluster. +func PullController(apiClient *clients.Settings, name, nsname string) (*ControllerBuilder, error) { + glog.V(100).Infof("Pulling existing kedaController name %s in namespace %s from cluster", name, nsname) + + if apiClient == nil { + glog.V(100).Infof("The apiClient is empty") + + return nil, fmt.Errorf("kedaController 'apiClient' cannot be empty") + } + + builder := ControllerBuilder{ + apiClient: apiClient.Client, + Definition: &kedav1alpha1.KedaController{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: nsname, + }, + }, + } + + if name == "" { + glog.V(100).Infof("The name of the kedaController is empty") + + return nil, fmt.Errorf("kedaController 'name' cannot be empty") + } + + if nsname == "" { + glog.V(100).Infof("The namespace of the kedaController is empty") + + return nil, fmt.Errorf("kedaController 'nsname' cannot be empty") + } + + if !builder.Exists() { + return nil, fmt.Errorf("kedaController object %s does not exist in namespace %s", name, nsname) + } + + builder.Definition = builder.Object + + return &builder, nil +} + +// Get fetches the defined kedaController from the cluster. +func (builder *ControllerBuilder) Get() (*kedav1alpha1.KedaController, error) { + if valid, err := builder.validate(); !valid { + return nil, err + } + + glog.V(100).Infof("Getting kedaController %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + kedaObj := &kedav1alpha1.KedaController{} + err := builder.apiClient.Get(context.TODO(), goclient.ObjectKey{ + Name: builder.Definition.Name, + Namespace: builder.Definition.Namespace, + }, kedaObj) + + if err != nil { + return nil, err + } + + return kedaObj, nil +} + +// Create makes a kedaController in the cluster and stores the created object in struct. +func (builder *ControllerBuilder) Create() (*ControllerBuilder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Creating the kedaController %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + var err error + if !builder.Exists() { + err = builder.apiClient.Create(context.TODO(), builder.Definition) + if err == nil { + builder.Object = builder.Definition + } + } + + return builder, err +} + +// Delete removes kedaController from a cluster. +func (builder *ControllerBuilder) Delete() (*ControllerBuilder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Deleting the kedaController %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + if !builder.Exists() { + glog.V(100).Infof("kedaController %s in namespace %s cannot be deleted because it does not exist", + builder.Definition.Name, builder.Definition.Namespace) + + builder.Object = nil + + return builder, nil + } + + err := builder.apiClient.Delete(context.TODO(), builder.Definition) + + if err != nil { + return builder, fmt.Errorf("can not delete kedaController: %w", err) + } + + builder.Object = nil + + return builder, nil +} + +// Exists checks whether the given kedaController exists. +func (builder *ControllerBuilder) Exists() bool { + if valid, _ := builder.validate(); !valid { + return false + } + + glog.V(100).Infof("Checking if kedaController %s exists in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + var err error + builder.Object, err = builder.Get() + + return err == nil || !k8serrors.IsNotFound(err) +} + +// Update renovates the existing kedaController object with kedaController definition in builder. +func (builder *ControllerBuilder) Update() (*ControllerBuilder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Updating kedaController %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + err := builder.apiClient.Update(context.TODO(), builder.Definition) + + if err != nil { + glog.V(100).Infof( + msg.FailToUpdateError("kedaController", builder.Definition.Name, builder.Definition.Namespace)) + + return nil, err + } + + builder.Object = builder.Definition + + return builder, nil +} + +// WithAdmissionWebhooks sets the kedaController operator's profile. +func (builder *ControllerBuilder) WithAdmissionWebhooks( + admissionWebhooks kedav1alpha1.KedaAdmissionWebhooksSpec) *ControllerBuilder { + glog.V(100).Infof( + "Adding admissionWebhooks to kedaController %s in namespace %s; admissionWebhooks %v", + builder.Definition.Name, builder.Definition.Namespace, admissionWebhooks) + + if valid, _ := builder.validate(); !valid { + return builder + } + + builder.Definition.Spec.AdmissionWebhooks = admissionWebhooks + + return builder +} + +// WithOperator sets the kedaController operator's profile. +func (builder *ControllerBuilder) WithOperator( + operator kedav1alpha1.KedaOperatorSpec) *ControllerBuilder { + glog.V(100).Infof( + "Adding operator to kedaController %s in namespace %s; operator %v", + builder.Definition.Name, builder.Definition.Namespace, operator) + + if valid, _ := builder.validate(); !valid { + return builder + } + + builder.Definition.Spec.Operator = operator + + return builder +} + +// WithMetricsServer sets the kedaController operator's metricsServer. +func (builder *ControllerBuilder) WithMetricsServer( + metricsServer kedav1alpha1.KedaMetricsServerSpec) *ControllerBuilder { + glog.V(100).Infof( + "Adding metricsServer to kedaController %s in namespace %s; metricsServer %v", + builder.Definition.Name, builder.Definition.Namespace, metricsServer) + + if valid, _ := builder.validate(); !valid { + return builder + } + + builder.Definition.Spec.MetricsServer = metricsServer + + return builder +} + +// WithWatchNamespace sets the kedaController operator's watchNamespace. +func (builder *ControllerBuilder) WithWatchNamespace( + watchNamespace string) *ControllerBuilder { + glog.V(100).Infof( + "Adding watchNamespace to kedaController %s in namespace %s; watchNamespace %v", + builder.Definition.Name, builder.Definition.Namespace, watchNamespace) + + if valid, _ := builder.validate(); !valid { + return builder + } + + if watchNamespace == "" { + glog.V(100).Infof("The watchNamespace is empty") + + builder.errorMsg = "'watchNamespace' argument cannot be empty" + + return builder + } + + builder.Definition.Spec.WatchNamespace = watchNamespace + + return builder +} + +// validate will check that the builder and builder definition are properly initialized before +// accessing any member fields. +func (builder *ControllerBuilder) validate() (bool, error) { + resourceCRD := "KedaController" + + if builder == nil { + glog.V(100).Infof("The %s builder is uninitialized", resourceCRD) + + return false, fmt.Errorf("error: received nil %s builder", resourceCRD) + } + + if builder.Definition == nil { + glog.V(100).Infof("The %s is undefined", resourceCRD) + + return false, fmt.Errorf(msg.UndefinedCrdObjectErrString(resourceCRD)) + } + + if builder.apiClient == nil { + glog.V(100).Infof("The %s builder apiclient is nil", resourceCRD) + + return false, fmt.Errorf("%s builder cannot have nil apiClient", resourceCRD) + } + + return true, nil +} diff --git a/vendor/github.com/openshift-kni/eco-goinfra/pkg/keda/scaleobject.go b/vendor/github.com/openshift-kni/eco-goinfra/pkg/keda/scaleobject.go new file mode 100644 index 000000000..fda6801a3 --- /dev/null +++ b/vendor/github.com/openshift-kni/eco-goinfra/pkg/keda/scaleobject.go @@ -0,0 +1,358 @@ +package keda + +import ( + "context" + "fmt" + + kedav2v1alpha1 "github.com/kedacore/keda/v2/apis/keda/v1alpha1" + + "github.com/golang/glog" + "github.com/openshift-kni/eco-goinfra/pkg/clients" + "github.com/openshift-kni/eco-goinfra/pkg/msg" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + goclient "sigs.k8s.io/controller-runtime/pkg/client" +) + +// ScaledObjectBuilder provides a struct for ScaledObject object from the cluster +// and a ScaledObject definition. +type ScaledObjectBuilder struct { + // ScaledObject definition, used to create the ScaledObject object. + Definition *kedav2v1alpha1.ScaledObject + // Created ScaledObject object. + Object *kedav2v1alpha1.ScaledObject + // Used to store latest error message upon defining or mutating ScaledObject definition. + errorMsg string + // api client to interact with the cluster. + apiClient goclient.Client +} + +// NewScaledObjectBuilder creates a new instance of ScaledObjectBuilder. +func NewScaledObjectBuilder( + apiClient *clients.Settings, name, nsname string) *ScaledObjectBuilder { + glog.V(100).Infof( + "Initializing new scaledObject structure with the following params: "+ + "name: %s, namespace: %s", name, nsname) + + if apiClient == nil { + glog.V(100).Infof("scaledObject 'apiClient' cannot be empty") + + return nil + } + + builder := &ScaledObjectBuilder{ + apiClient: apiClient.Client, + Definition: &kedav2v1alpha1.ScaledObject{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: nsname, + }, + }, + } + + if name == "" { + glog.V(100).Infof("The name of the scaledObject is empty") + + builder.errorMsg = "scaledObject 'name' cannot be empty" + + return builder + } + + if nsname == "" { + glog.V(100).Infof("The nsname of the scaledObject is empty") + + builder.errorMsg = "scaledObject 'nsname' cannot be empty" + + return builder + } + + return builder +} + +// PullScaledObject pulls existing scaledObject from cluster. +func PullScaledObject(apiClient *clients.Settings, name, nsname string) (*ScaledObjectBuilder, error) { + glog.V(100).Infof("Pulling existing scaledObject name %s in namespace %s from cluster", + name, nsname) + + if apiClient == nil { + glog.V(100).Infof("The apiClient is empty") + + return nil, fmt.Errorf("scaledObject 'apiClient' cannot be empty") + } + + builder := ScaledObjectBuilder{ + apiClient: apiClient.Client, + Definition: &kedav2v1alpha1.ScaledObject{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: nsname, + }, + }, + } + + if name == "" { + glog.V(100).Infof("The name of the scaledObject is empty") + + return nil, fmt.Errorf("scaledObject 'name' cannot be empty") + } + + if nsname == "" { + glog.V(100).Infof("The namespace of the scaledObject is empty") + + return nil, fmt.Errorf("scaledObject 'nsname' cannot be empty") + } + + if !builder.Exists() { + return nil, fmt.Errorf("scaledObject object %s does not exist in namespace %s", name, nsname) + } + + builder.Definition = builder.Object + + return &builder, nil +} + +// Get fetches the defined scaledObject from the cluster. +func (builder *ScaledObjectBuilder) Get() (*kedav2v1alpha1.ScaledObject, error) { + if valid, err := builder.validate(); !valid { + return nil, err + } + + glog.V(100).Infof("Getting scaledObject %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + scaleObjectObj := &kedav2v1alpha1.ScaledObject{} + err := builder.apiClient.Get(context.TODO(), goclient.ObjectKey{ + Name: builder.Definition.Name, + Namespace: builder.Definition.Namespace, + }, scaleObjectObj) + + if err != nil { + return nil, err + } + + return scaleObjectObj, nil +} + +// Create makes a scaledObject in the cluster and stores the created object in struct. +func (builder *ScaledObjectBuilder) Create() (*ScaledObjectBuilder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Creating the scaledObject %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + var err error + if !builder.Exists() { + err = builder.apiClient.Create(context.TODO(), builder.Definition) + if err == nil { + builder.Object = builder.Definition + } + } + + return builder, err +} + +// Delete removes scaledObject from a cluster. +func (builder *ScaledObjectBuilder) Delete() (*ScaledObjectBuilder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Deleting the scaledObject %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + if !builder.Exists() { + glog.V(100).Infof("scaledObject %s in namespace %s cannot be deleted"+ + " because it does not exist", + builder.Definition.Name, builder.Definition.Namespace) + + builder.Object = nil + + return builder, nil + } + + err := builder.apiClient.Delete(context.TODO(), builder.Definition) + + if err != nil { + return builder, fmt.Errorf("can not delete scaledObject: %w", err) + } + + builder.Object = nil + + return builder, nil +} + +// Exists checks whether the given scaledObject exists. +func (builder *ScaledObjectBuilder) Exists() bool { + if valid, _ := builder.validate(); !valid { + return false + } + + glog.V(100).Infof("Checking if scaledObject %s exists in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + var err error + builder.Object, err = builder.Get() + + return err == nil || !k8serrors.IsNotFound(err) +} + +// Update renovates the existing scaledObject object with scaledObject definition in builder. +func (builder *ScaledObjectBuilder) Update() (*ScaledObjectBuilder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Updating scaledObject %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + err := builder.apiClient.Update(context.TODO(), builder.Definition) + + if err != nil { + glog.V(100).Infof( + msg.FailToUpdateError("scaledObject", builder.Definition.Name, builder.Definition.Namespace)) + + return nil, err + } + + builder.Object = builder.Definition + + return builder, nil +} + +// WithTriggers sets the scaledObject operator's maxReplicaCount. +func (builder *ScaledObjectBuilder) WithTriggers( + triggers []kedav2v1alpha1.ScaleTriggers) *ScaledObjectBuilder { + glog.V(100).Infof( + "Adding triggers to scaledObject %s in namespace %s; triggers %v", + builder.Definition.Name, builder.Definition.Namespace, triggers) + + if valid, _ := builder.validate(); !valid { + return builder + } + + if len(triggers) == 0 { + glog.V(100).Infof("'triggers' argument cannot be empty") + + builder.errorMsg = "'triggers' argument cannot be empty" + + return builder + } + + builder.Definition.Spec.Triggers = triggers + + return builder +} + +// WithMaxReplicaCount sets the scaledObject operator's maxReplicaCount. +func (builder *ScaledObjectBuilder) WithMaxReplicaCount( + maxReplicaCount int32) *ScaledObjectBuilder { + glog.V(100).Infof( + "Adding maxReplicaCount to scaledObject %s in namespace %s; maxReplicaCount %v", + builder.Definition.Name, builder.Definition.Namespace, maxReplicaCount) + + if valid, _ := builder.validate(); !valid { + return builder + } + + builder.Definition.Spec.MaxReplicaCount = &maxReplicaCount + + return builder +} + +// WithMinReplicaCount sets the scaledObject operator's minReplicaCount. +func (builder *ScaledObjectBuilder) WithMinReplicaCount( + minReplicaCount int32) *ScaledObjectBuilder { + glog.V(100).Infof( + "Adding minReplicaCount to scaledObject %s in namespace %s; minReplicaCount %v", + builder.Definition.Name, builder.Definition.Namespace, minReplicaCount) + + if valid, _ := builder.validate(); !valid { + return builder + } + + builder.Definition.Spec.MinReplicaCount = &minReplicaCount + + return builder +} + +// WithCooldownPeriod sets the scaledObject operator's cooldownPeriod. +func (builder *ScaledObjectBuilder) WithCooldownPeriod( + cooldownPeriod int32) *ScaledObjectBuilder { + glog.V(100).Infof( + "Adding cooldownPeriod to scaledObject %s in namespace %s; cooldownPeriod %v", + builder.Definition.Name, builder.Definition.Namespace, cooldownPeriod) + + if valid, _ := builder.validate(); !valid { + return builder + } + + builder.Definition.Spec.CooldownPeriod = &cooldownPeriod + + return builder +} + +// WithPollingInterval sets the scaledObject operator's pollingInterval. +func (builder *ScaledObjectBuilder) WithPollingInterval( + pollingInterval int32) *ScaledObjectBuilder { + glog.V(100).Infof( + "Adding pollingInterval to scaledObject %s in namespace %s; pollingInterval %v", + builder.Definition.Name, builder.Definition.Namespace, pollingInterval) + + if valid, _ := builder.validate(); !valid { + return builder + } + + builder.Definition.Spec.PollingInterval = &pollingInterval + + return builder +} + +// WithScaleTargetRef sets the scaledObject operator's scaleTargetRef. +func (builder *ScaledObjectBuilder) WithScaleTargetRef( + scaleTargetRef kedav2v1alpha1.ScaleTarget) *ScaledObjectBuilder { + glog.V(100).Infof( + "Adding scaleTargetRef to scaledObject %s in namespace %s; scaleTargetRef %v", + builder.Definition.Name, builder.Definition.Namespace, scaleTargetRef) + + if valid, _ := builder.validate(); !valid { + return builder + } + + builder.Definition.Spec.ScaleTargetRef = &scaleTargetRef + + return builder +} + +// validate will check that the builder and builder definition are properly initialized before +// accessing any member fields. +func (builder *ScaledObjectBuilder) validate() (bool, error) { + resourceCRD := "ScaledObject" + + if builder == nil { + glog.V(100).Infof("The %s builder is uninitialized", resourceCRD) + + return false, fmt.Errorf("error: received nil %s builder", resourceCRD) + } + + if builder.Definition == nil { + glog.V(100).Infof("The %s is undefined", resourceCRD) + + return false, fmt.Errorf(msg.UndefinedCrdObjectErrString(resourceCRD)) + } + + if builder.apiClient == nil { + glog.V(100).Infof("The %s builder apiclient is nil", resourceCRD) + + return false, fmt.Errorf("%s builder cannot have nil apiClient", resourceCRD) + } + + if builder.errorMsg != "" { + glog.V(100).Infof("The %s builder has error message: %s", resourceCRD, builder.errorMsg) + + return false, fmt.Errorf(builder.errorMsg) + } + + return true, nil +} diff --git a/vendor/github.com/openshift-kni/eco-goinfra/pkg/keda/triggerauthentication.go b/vendor/github.com/openshift-kni/eco-goinfra/pkg/keda/triggerauthentication.go new file mode 100644 index 000000000..c7b22f28a --- /dev/null +++ b/vendor/github.com/openshift-kni/eco-goinfra/pkg/keda/triggerauthentication.go @@ -0,0 +1,279 @@ +package keda + +import ( + "context" + "fmt" + + kedav2v1alpha1 "github.com/kedacore/keda/v2/apis/keda/v1alpha1" + + "github.com/golang/glog" + "github.com/openshift-kni/eco-goinfra/pkg/clients" + "github.com/openshift-kni/eco-goinfra/pkg/msg" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + goclient "sigs.k8s.io/controller-runtime/pkg/client" +) + +// TriggerAuthenticationBuilder provides a struct for TriggerAuthentication object from the cluster +// and a TriggerAuthentication definition. +type TriggerAuthenticationBuilder struct { + // TriggerAuthentication definition, used to create the TriggerAuthentication object. + Definition *kedav2v1alpha1.TriggerAuthentication + // Created TriggerAuthentication object. + Object *kedav2v1alpha1.TriggerAuthentication + // Used to store latest error message upon defining or mutating TriggerAuthentication definition. + errorMsg string + // api client to interact with the cluster. + apiClient goclient.Client +} + +// NewTriggerAuthenticationBuilder creates a new instance of TriggerAuthenticationBuilder. +func NewTriggerAuthenticationBuilder( + apiClient *clients.Settings, name, nsname string) *TriggerAuthenticationBuilder { + glog.V(100).Infof( + "Initializing new triggerAuthentication structure with the following params: "+ + "name: %s, namespace: %s", name, nsname) + + if apiClient == nil { + glog.V(100).Infof("triggerAuthentication 'apiClient' cannot be empty") + + return nil + } + + builder := &TriggerAuthenticationBuilder{ + apiClient: apiClient.Client, + Definition: &kedav2v1alpha1.TriggerAuthentication{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: nsname, + }, + }, + } + + if name == "" { + glog.V(100).Infof("The name of the triggerAuthentication is empty") + + builder.errorMsg = "triggerAuthentication 'name' cannot be empty" + + return builder + } + + if nsname == "" { + glog.V(100).Infof("The nsname of the triggerAuthentication is empty") + + builder.errorMsg = "triggerAuthentication 'nsname' cannot be empty" + + return builder + } + + return builder +} + +// PullTriggerAuthentication pulls existing triggerAuthentication from cluster. +func PullTriggerAuthentication(apiClient *clients.Settings, + name, nsname string) (*TriggerAuthenticationBuilder, error) { + glog.V(100).Infof("Pulling existing triggerAuthentication name %s in namespace %s from cluster", + name, nsname) + + if apiClient == nil { + glog.V(100).Infof("The apiClient is empty") + + return nil, fmt.Errorf("triggerAuthentication 'apiClient' cannot be empty") + } + + builder := TriggerAuthenticationBuilder{ + apiClient: apiClient.Client, + Definition: &kedav2v1alpha1.TriggerAuthentication{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: nsname, + }, + }, + } + + if name == "" { + glog.V(100).Infof("The name of the triggerAuthentication is empty") + + return nil, fmt.Errorf("triggerAuthentication 'name' cannot be empty") + } + + if nsname == "" { + glog.V(100).Infof("The namespace of the triggerAuthentication is empty") + + return nil, fmt.Errorf("triggerAuthentication 'nsname' cannot be empty") + } + + if !builder.Exists() { + return nil, fmt.Errorf("triggerAuthentication object %s does not exist in namespace %s", name, nsname) + } + + builder.Definition = builder.Object + + return &builder, nil +} + +// Get fetches the defined triggerAuthentication from the cluster. +func (builder *TriggerAuthenticationBuilder) Get() (*kedav2v1alpha1.TriggerAuthentication, error) { + if valid, err := builder.validate(); !valid { + return nil, err + } + + glog.V(100).Infof("Getting triggerAuthentication %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + triggerAuthenticationObj := &kedav2v1alpha1.TriggerAuthentication{} + err := builder.apiClient.Get(context.TODO(), goclient.ObjectKey{ + Name: builder.Definition.Name, + Namespace: builder.Definition.Namespace, + }, triggerAuthenticationObj) + + if err != nil { + return nil, err + } + + return triggerAuthenticationObj, nil +} + +// Create makes a triggerAuthentication in the cluster and stores the created object in struct. +func (builder *TriggerAuthenticationBuilder) Create() (*TriggerAuthenticationBuilder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Creating the triggerAuthentication %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + var err error + if !builder.Exists() { + err = builder.apiClient.Create(context.TODO(), builder.Definition) + if err == nil { + builder.Object = builder.Definition + } + } + + return builder, err +} + +// Delete removes triggerAuthentication from a cluster. +func (builder *TriggerAuthenticationBuilder) Delete() (*TriggerAuthenticationBuilder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Deleting the triggerAuthentication %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + if !builder.Exists() { + glog.V(100).Infof("triggerAuthentication %s in namespace %s cannot be deleted"+ + " because it does not exist", + builder.Definition.Name, builder.Definition.Namespace) + + builder.Object = nil + + return builder, nil + } + + err := builder.apiClient.Delete(context.TODO(), builder.Definition) + + if err != nil { + return builder, fmt.Errorf("can not delete triggerAuthentication: %w", err) + } + + builder.Object = nil + + return builder, nil +} + +// Exists checks whether the given triggerAuthentication exists. +func (builder *TriggerAuthenticationBuilder) Exists() bool { + if valid, _ := builder.validate(); !valid { + return false + } + + glog.V(100).Infof("Checking if triggerAuthentication %s exists in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + var err error + builder.Object, err = builder.Get() + + return err == nil || !k8serrors.IsNotFound(err) +} + +// Update renovates the existing triggerAuthentication object with triggerAuthentication definition in builder. +func (builder *TriggerAuthenticationBuilder) Update() (*TriggerAuthenticationBuilder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Updating triggerAuthentication %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + err := builder.apiClient.Update(context.TODO(), builder.Definition) + + if err != nil { + glog.V(100).Infof( + msg.FailToUpdateError("triggerAuthentication", builder.Definition.Name, builder.Definition.Namespace)) + + return nil, err + } + + builder.Object = builder.Definition + + return builder, nil +} + +// WithSecretTargetRef sets the triggerAuthentication operator's secretTargetRef. +func (builder *TriggerAuthenticationBuilder) WithSecretTargetRef( + secretTargetRef []kedav2v1alpha1.AuthSecretTargetRef) *TriggerAuthenticationBuilder { + glog.V(100).Infof( + "Adding secretTargetRef to triggerAuthentication %s in namespace %s; secretTargetRef %v", + builder.Definition.Name, builder.Definition.Namespace, secretTargetRef) + + if valid, _ := builder.validate(); !valid { + return builder + } + + if len(secretTargetRef) == 0 { + glog.V(100).Infof("'secretTargetRef' argument cannot be empty") + + builder.errorMsg = "'secretTargetRef' argument cannot be empty" + + return builder + } + + builder.Definition.Spec.SecretTargetRef = secretTargetRef + + return builder +} + +// validate will check that the builder and builder definition are properly initialized before +// accessing any member fields. +func (builder *TriggerAuthenticationBuilder) validate() (bool, error) { + resourceCRD := "TriggerAuthentication" + + if builder == nil { + glog.V(100).Infof("The %s builder is uninitialized", resourceCRD) + + return false, fmt.Errorf("error: received nil %s builder", resourceCRD) + } + + if builder.Definition == nil { + glog.V(100).Infof("The %s is undefined", resourceCRD) + + return false, fmt.Errorf(msg.UndefinedCrdObjectErrString(resourceCRD)) + } + + if builder.apiClient == nil { + glog.V(100).Infof("The %s builder apiclient is nil", resourceCRD) + + return false, fmt.Errorf("%s builder cannot have nil apiClient", resourceCRD) + } + + if builder.errorMsg != "" { + glog.V(100).Infof("The %s builder has error message: %s", resourceCRD, builder.errorMsg) + + return false, fmt.Errorf(builder.errorMsg) + } + + return true, nil +} diff --git a/vendor/github.com/openshift-kni/eco-goinfra/pkg/pod/pod.go b/vendor/github.com/openshift-kni/eco-goinfra/pkg/pod/pod.go index d677cc632..6b484dca7 100644 --- a/vendor/github.com/openshift-kni/eco-goinfra/pkg/pod/pod.go +++ b/vendor/github.com/openshift-kni/eco-goinfra/pkg/pod/pod.go @@ -223,6 +223,31 @@ func (builder *Builder) DeleteAndWait(timeout time.Duration) (*Builder, error) { return builder, nil } +// DeleteImmediate removes the pod immediately and resets the builder object. +func (builder *Builder) DeleteImmediate() (*Builder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Immediately deleting pod %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + if !builder.Exists() { + return nil, fmt.Errorf("pod cannot be deleted because it does not exist") + } + + err := builder.apiClient.Pods(builder.Definition.Namespace).Delete( + context.TODO(), builder.Object.Name, metav1.DeleteOptions{GracePeriodSeconds: ptr.To(int64(0))}) + + if err != nil { + return builder, fmt.Errorf("can not immediately delete pod: %w", err) + } + + builder.Object = nil + + return builder, nil +} + // CreateAndWaitUntilRunning creates the pod object and waits until the pod is running. func (builder *Builder) CreateAndWaitUntilRunning(timeout time.Duration) (*Builder, error) { if valid, err := builder.validate(); !valid { diff --git a/vendor/modules.txt b/vendor/modules.txt index dad92d5d3..0b3c5e30d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -638,7 +638,7 @@ github.com/openshift-kni/cluster-group-upgrades-operator/pkg/generated/clientset github.com/openshift-kni/cluster-group-upgrades-operator/pkg/generated/clientset/versioned/scheme github.com/openshift-kni/cluster-group-upgrades-operator/pkg/generated/clientset/versioned/typed/clustergroupupgrades/v1alpha1 github.com/openshift-kni/cluster-group-upgrades-operator/pkg/generated/clientset/versioned/typed/clustergroupupgrades/v1alpha1/fake -# github.com/openshift-kni/eco-goinfra v0.0.0-20240620154035-1f702e37c052 +# github.com/openshift-kni/eco-goinfra v0.0.0-20240621192821-7c55fda74f32 ## explicit; go 1.22 github.com/openshift-kni/eco-goinfra/pkg/apiservers github.com/openshift-kni/eco-goinfra/pkg/argocd/argocdtypes @@ -659,6 +659,7 @@ github.com/openshift-kni/eco-goinfra/pkg/hive github.com/openshift-kni/eco-goinfra/pkg/imageregistry github.com/openshift-kni/eco-goinfra/pkg/infrastructure github.com/openshift-kni/eco-goinfra/pkg/ingress +github.com/openshift-kni/eco-goinfra/pkg/keda github.com/openshift-kni/eco-goinfra/pkg/kmm github.com/openshift-kni/eco-goinfra/pkg/lca github.com/openshift-kni/eco-goinfra/pkg/lso From 8a0de42f84190c376badae58096b53db065addc1 Mon Sep 17 00:00:00 2001 From: Elena German Date: Wed, 12 Jun 2024 05:08:33 -0400 Subject: [PATCH 2/5] vcore:keda test suite --- .../internal/vcorecommon/metallb-operator.go | 2 +- .../vcore/internal/vcorecommon/redis.go | 2 +- .../vcore/internal/vcoreparams/const.go | 15 +++++++++++++++ .../vcore/tests/00_validate_basic_deployment.go | 2 ++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/tests/system-tests/vcore/internal/vcorecommon/metallb-operator.go b/tests/system-tests/vcore/internal/vcorecommon/metallb-operator.go index 5b772c4bd..d58103178 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/metallb-operator.go +++ b/tests/system-tests/vcore/internal/vcorecommon/metallb-operator.go @@ -117,7 +117,7 @@ func VerifyMetalLBOperatorDeployment(ctx SpecContext) { // VerifyMetaLBSuite container that contains tests for MetalLB verification. func VerifyMetaLBSuite() { Describe( - "NMState validation", + "MetalLB validation", Label(vcoreparams.LabelVCoreOperators), func() { BeforeAll(func() { By(fmt.Sprintf("Asserting %s folder exists", vcoreparams.ConfigurationFolderName)) diff --git a/tests/system-tests/vcore/internal/vcorecommon/redis.go b/tests/system-tests/vcore/internal/vcorecommon/redis.go index bd632ab14..7f4b2463b 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/redis.go +++ b/tests/system-tests/vcore/internal/vcorecommon/redis.go @@ -68,7 +68,7 @@ func VerifyRedisDeploymentProcedure(ctx SpecContext) { imageURL := fmt.Sprintf("%s/%s", redisImageRepository, redisImageName) isDisconnected, err := platform.IsDisconnectedDeployment(APIClient) - Expect(err).ToNot(HaveOccurred(), "failed to detect t a deployment type") + Expect(err).ToNot(HaveOccurred(), "failed to detect a deployment type") if !isDisconnected { glog.V(vcoreparams.VCoreLogLevel).Info("The connected deployment type was detected, " + diff --git a/tests/system-tests/vcore/internal/vcoreparams/const.go b/tests/system-tests/vcore/internal/vcoreparams/const.go index b7e956307..8d0152670 100644 --- a/tests/system-tests/vcore/internal/vcoreparams/const.go +++ b/tests/system-tests/vcore/internal/vcoreparams/const.go @@ -177,4 +177,19 @@ const ( // SRIOVWebhookDaemonsetName is a SR-IOV operator webhook daemonset name. SRIOVWebhookDaemonsetName = "operator-webhook" + + // KedaNamespace is a keda operator namespace. + KedaNamespace = "openshift-keda" + + // KedaWatchNamespace is a keda watch namespace name. + KedaWatchNamespace = "test-appspace" + + // KedaSubscriptionName is a keda operator subscription name. + KedaSubscriptionName = "openshift-custom-metrics-autoscaler-operator" + + // KedaDeploymentName is a keda operator deployment name. + KedaDeploymentName = "custom-metrics-autoscaler-operator" + + // KedaControllerName is a kedaController name. + KedaControllerName = "keda" ) diff --git a/tests/system-tests/vcore/tests/00_validate_basic_deployment.go b/tests/system-tests/vcore/tests/00_validate_basic_deployment.go index 232b154d3..c5bb7147f 100644 --- a/tests/system-tests/vcore/tests/00_validate_basic_deployment.go +++ b/tests/system-tests/vcore/tests/00_validate_basic_deployment.go @@ -37,4 +37,6 @@ var _ = Describe( vcorecommon.VerifyNTOSuite() vcorecommon.VerifySRIOVSuite() + + vcorecommon.VerifyKedaSuite() }) From 84527f7b22671639b97be557392661f0751ffabe Mon Sep 17 00:00:00 2001 From: Elena German Date: Mon, 17 Jun 2024 15:28:52 -0400 Subject: [PATCH 3/5] keda test suite --- go.mod | 4 +- kubeconfig | 19 + .../internal/cleanup/namespace.go | 49 --- .../internal/mirroring/mirror-images.go | 7 +- tests/system-tests/internal/ocpcli/ocpcli.go | 30 +- .../internal/config-files/clo-instance.yaml | 69 --- .../config-files/keda-test-app-load-job.yaml | 24 ++ .../internal/monitoring/servicemonitor.go | 364 ++++++++++++++++ .../internal/vcorecommon/esk-clo-operator.go | 2 +- .../internal/vcorecommon/keda-validation.go | 394 +++++++++++++++--- .../vcorecommon/post-deployment-config.go | 2 +- .../internal/vcorecommon/smo-validation.go | 2 +- .../internal/vcorecommon/sriov-validation.go | 6 +- .../vcore/internal/vcoreparams/const.go | 3 + 14 files changed, 778 insertions(+), 197 deletions(-) create mode 100644 kubeconfig delete mode 100644 tests/system-tests/internal/cleanup/namespace.go delete mode 100644 tests/system-tests/vcore/internal/config-files/clo-instance.yaml create mode 100644 tests/system-tests/vcore/internal/config-files/keda-test-app-load-job.yaml create mode 100644 tests/system-tests/vcore/internal/monitoring/servicemonitor.go diff --git a/go.mod b/go.mod index e2b403b82..1768f900c 100644 --- a/go.mod +++ b/go.mod @@ -42,10 +42,12 @@ require ( require ( github.com/kedacore/keda-olm-operator v0.0.0-20240501182040-762f6be5a942 + github.com/kedacore/keda/v2 v2.14.0 github.com/openshift-kni/lifecycle-agent v0.0.0-20240606123201-0c45cd13c2f1 github.com/openshift/client-go v0.0.1 github.com/openshift/installer v0.0.0-00010101000000-000000000000 github.com/povsister/scp v0.0.0-20210427074412-33febfd9f13e + github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.73.2 github.com/stretchr/testify v1.9.0 github.com/vmware-tanzu/velero v1.13.2 k8s.io/utils v0.0.0-20240310230437-4693a0247e57 @@ -64,7 +66,6 @@ require ( github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 // indirect github.com/gorilla/websocket v1.5.1 // indirect github.com/kdomanski/iso9660 v0.2.1 // indirect - github.com/kedacore/keda/v2 v2.14.0 // indirect github.com/lib/pq v1.10.9 // indirect github.com/metal3-io/baremetal-operator/pkg/hardwareutils v0.5.1 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect @@ -72,7 +73,6 @@ require ( github.com/openshift-kni/numaresources-operator v0.4.16-0rc0 // indirect github.com/openshift/cluster-logging-operator v0.0.0-20240606085930-750f369019d4 // indirect github.com/openshift/elasticsearch-operator v0.0.0-20220613183908-e1648e67c298 // indirect - github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.73.2 // indirect github.com/stmcginnis/gofish v0.15.1-0.20231121142100-22a60a77be91 // indirect github.com/stolostron/cluster-lifecycle-api v0.0.0-20240109072430-f5fe6043d1f8 // indirect github.com/stolostron/klusterlet-addon-controller v0.0.0-20240606130554-01338045271a // indirect diff --git a/kubeconfig b/kubeconfig new file mode 100644 index 000000000..1f0035ae1 --- /dev/null +++ b/kubeconfig @@ -0,0 +1,19 @@ +apiVersion: v1 +clusters: +- cluster: + certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURoekNDQW0rZ0F3SUJBZ0lJYnk5akVHV3QvWGd3RFFZSktvWklodmNOQVFFTEJRQXdKakVrTUNJR0ExVUUKQXd3YmFXNW5jbVZ6Y3kxdmNHVnlZWFJ2Y2tBeE56RTROalF4TkRNek1CNFhEVEkwTURZeE56RTJNak0xTTFvWApEVEkyTURZeE56RTJNak0xTkZvd016RXhNQzhHQTFVRUF3d29LaTVoY0hCekxtdHVhUzF4WlMwMk9TNXNZV0l1ClpXNW5MbkprZFRJdWNtVmthR0YwTG1OdmJUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0MKZ2dFQkFNSHNHdEFjVDJkamZ2WFM1SjFYOEI5MnU0VTZKSVI2dnZBU3phZGpveFhqUmsrb2xYdHFmU1BBOFJWcQovUWF5U1dyVGNPWDNlcE53M3c0MTA5dkEzMW1ZbU83M2Y3bjVUUk40OXUwU3BxdTFTODRuSGlNbEtGR0VlR2RhCnFKRllPMldYYTB3ekMwT1FkSU5zK0F4TzZBeGVvVHpjcmxHdGZRZG40RVdYU0orSFhkc0hYdzZtbFpDOFRzQ0oKZGd4djNnZktlS3Q3VTVKb0l0a2Q2aVRGdlRLV0todGFIaHNzNjVmZ0xNZjdSRXZ1QkZLN2x6K1pQT0pLclZOegpwZ25UTWROUVBpb1JpREtlOEo3T2p0Nmo5SG5vV3lKN3MzM3JqRjZxdmhlckUveWxWUWd5Q28wcEFQUVl1SGRmCjU0ZVUycE83T0tmTEVzS0VrOU45NHZzV1ZCRUNBd0VBQWFPQnF6Q0JxREFPQmdOVkhROEJBZjhFQkFNQ0JhQXcKRXdZRFZSMGxCQXd3Q2dZSUt3WUJCUVVIQXdFd0RBWURWUjBUQVFIL0JBSXdBREFkQmdOVkhRNEVGZ1FVRGp5dwo5czMzdndYWlZYbVhQd1k2N2Fsa3VPQXdId1lEVlIwakJCZ3dGb0FVaU02UkZTQnYybE1ZMzVFcGFucjV2UzIwCm10SXdNd1lEVlIwUkJDd3dLb0lvS2k1aGNIQnpMbXR1YVMxeFpTMDJPUzVzWVdJdVpXNW5MbkprZFRJdWNtVmsKYUdGMExtTnZiVEFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBZndiRUM3ZE1kVE5MV24zRWozdkNCdDJudWs5awpBeFZwNDdLN3Y4elhobzIrTVlqdklML1FTbXAraGh6MVRzYXZQZ3lIMHlZdDNmZitoZWRCNzlGa3pha1ozQitJCnRUWXRxN0RGUHByUHNqUldiYWpteWFGWlo4UjFiOE9uZ0RRNVRFTWNseGxwM095eURlQjQ5U3BPQWs1RU0zK2MKRWpMWjlmeVVnZnlrbENNenV6MDB0TkhkSjNUdWJRYWZCVHp0MXYyQlBES2lDelZ3cmZidTZVL3d6WTJuaXVOWApWcGJQczAzT25QMldWSk13cU5IUS93THR5NDNHZlR3RHJsQXk3ZExwZ3AvdERkRHZJTkIyYVVZUVR2K2kxQnZyCnRONXd5UlEyVUlDS2R4RXJ3bGUrR21KRmlTZXRHZ1FCamQ4dWg5dTVmOGtSOGFFR0RwVnE4NzMrOEE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlERERDQ0FmU2dBd0lCQWdJQkFUQU5CZ2txaGtpRzl3MEJBUXNGQURBbU1TUXdJZ1lEVlFRRERCdHBibWR5ClpYTnpMVzl3WlhKaGRHOXlRREUzTVRnMk5ERTBNek13SGhjTk1qUXdOakUzTVRZeU16VXlXaGNOTWpZd05qRTMKTVRZeU16VXpXakFtTVNRd0lnWURWUVFEREJ0cGJtZHlaWE56TFc5d1pYSmhkRzl5UURFM01UZzJOREUwTXpNdwpnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDN1piYlR4Q0Qwb2xMSnhGQ3lsSGNCCk1UNk42QlZhM1ZGSjYxSmo3eWhIcUtaUFNGTktMMDhrZFA2UkhlZ1hOOEtkeEZUYkxZSDM2cW1CRkJ4L2VLeloKd1NuWjR1cktUcVUrNEw2VndRUmI5bkZRTTFyRVkyeldEM2ozZjlHYS81TEZsRlpReXJEZ0JNMEJNWUZzam1hbAp1dkJsekIwK082TXhONEZuL1R6dkZaRzBoblVjc1dkUXM3SmJnWlFXK2xZQm5ZTWwremdvTU5LczJuak5HdUIrCkRUc25kaW9RLzJuZHljSDhBM200UW1HVytCR0NOaTRYdmw4N1l6eTB2SFBhUHVNMDhxNGZCcWxpb2o0amRpejMKZkJLWUhaSmQ5bFZmWkpWdWNoTkVuRjcrZTcwRWdYcEtiSjF5cjVSTUxIVzEzMGFsL1NBN0ZCNjhzMWc5MWNHNQpBZ01CQUFHalJUQkRNQTRHQTFVZER3RUIvd1FFQXdJQ3BEQVNCZ05WSFJNQkFmOEVDREFHQVFIL0FnRUFNQjBHCkExVWREZ1FXQkJTSXpwRVZJRy9hVXhqZmtTbHFldm05TGJTYTBqQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUEKWlM5dXRRRWM5WmN2N0RCdjZXMXRhTXY2ak1xR0c2bENwM0hrWlRlT080TThlMnhudlpBMmxjaklaajJ0OW5rMgpkdTAzQm9rQzNxeS9XenhBTTZRM094YUh4Tk5GK0psYzdJUUo3a3hKak5pL0krKy82cktPemdmcytZT1dFLzRWCjgrS1RUUEUrQmhUZ0FXTjZ6OGlMNWdwZzZFZWtOTlFJSlJEK0FrQ1dNQkNlZEdrSHpvS1ZlR1VRbFRVQUlCOWcKbFdORUpLUDgrTHJ5dkx1UnZMaGszSGlZS0k3NUdXUExtVHF5ajk0NnJhU0R4WXdPUStaOHEvSStuWkNkN3d4TAozNDlsK3lxaXp2b0dWaGJPTjFBNFQyM0YwQnZrRURFUXJpa3pLb3BSQStYd2NaQklCU3Y3cVh4ZU1ZZkg0Y01qCnlUUEY4M1crUVJFa1lEazZWa3NxalE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEUURDQ0FpaWdBd0lCQWdJSUp3SWh0cEVYdU9jd0RRWUpLb1pJaHZjTkFRRUxCUUF3UGpFU01CQUdBMVVFCkN4TUpiM0JsYm5Ob2FXWjBNU2d3SmdZRFZRUURFeDlyZFdKbExXRndhWE5sY25abGNpMXNiMk5oYkdodmMzUXQKYzJsbmJtVnlNQjRYRFRJME1EWXhOekUyTURZMU1Gb1hEVE0wTURZeE5URTJNRFkxTUZvd1BqRVNNQkFHQTFVRQpDeE1KYjNCbGJuTm9hV1owTVNnd0pnWURWUVFERXg5cmRXSmxMV0Z3YVhObGNuWmxjaTFzYjJOaGJHaHZjM1F0CmMybG5ibVZ5TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF3U3N0VXUxYmVEdlgKMitkTFd3aUl2YkZ5dlZiQXYxUlJnZUlNY3M3ZUk5TWduZzhQVWRKblZRSXJHMjN3ZCtHR2dENTc5UEpWbUV4ZAo0dEZzb1laT0RvRFhCU214ZFhTUkFhelVoRWRsd1RjRFdreUJIWWtJRmM0bnVXajdaZHorTWxUU056RlkwZjVFCmhTTEs2TldZSnBqM3NDS1pXVXF0OGFYNUlTZ2xzWk5VMTRxdHVTbkZOZU90SzZ2RjVqZGZmTWVDUFNOS0J2VW0KVjlzQzYzaVRFMm5kb0k4OFpYczV5QTFlWnJhR1dpNEp6dmw5a0U0UnZySml3bHlhK2NUUHlMdEZNWmZxS3RWcwo1RW8wbjhGdEFzczJUL21OdTBwdDk0MGwyRlJwN2UyMy9SQTNTV1U4enZRZFo5ejU5aWxxZFBhcFlyZ3pOMU9UCnhIdVYxeHEvOVFJREFRQUJvMEl3UURBT0JnTlZIUThCQWY4RUJBTUNBcVF3RHdZRFZSMFRBUUgvQkFVd0F3RUIKL3pBZEJnTlZIUTRFRmdRVUo5RnZMU0Q5emFSakNuVCszVTFUbERweEpmRXdEUVlKS29aSWh2Y05BUUVMQlFBRApnZ0VCQURYNUh1V29JdXRlQThzR0Z4dmZpUTNjeDVCeHR0ckQwK3FIY0tOZWZEMk5aNXZpSERpdnFIZjRINzN3Cld6L0tuaEc2ZXU4N2g3KzBGeGNlZ0N3NGZyeHY4ZTIwaDBKcHhGdXIxWGVuWi9WVVZBK3V5dkhKOVoybXkwZkQKTitCbUp3SkFxZGlrMUt4VnhCSTRwYU15alhmVVduSWp1Qis5aUFkYjRMWkMvUTlxeFY2ZGtON1RCTzhHSmVmSgp6NGFJNnRzaDY4Ukhsem9sL3VzMkZXQnNtQW82Y0pPeGZJRVQ2emxiK1A4S29mLy8xZ0VXT282RVhjYUs4Vk0zCkFhY2tPTG5ZaVplbVNieFBqUmc3dzIxbWh6Zk0vMWx3bDhBbVU4MlRVVldLNUNzYmJkaks3L25rVktCRE5vY00KYkJtYmlwdGFmSUFYQmtEdmdML2VIa1Zsd3JNPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEVERDQ0FqU2dBd0lCQWdJSVZNcUhacEhiWWxRd0RRWUpLb1pJaHZjTkFRRUxCUUF3UkRFU01CQUdBMVVFCkN4TUpiM0JsYm5Ob2FXWjBNUzR3TEFZRFZRUURFeVZyZFdKbExXRndhWE5sY25abGNpMXpaWEoyYVdObExXNWwKZEhkdmNtc3RjMmxuYm1WeU1CNFhEVEkwTURZeE56RTJNRFkxTVZvWERUTTBNRFl4TlRFMk1EWTFNVm93UkRFUwpNQkFHQTFVRUN4TUpiM0JsYm5Ob2FXWjBNUzR3TEFZRFZRUURFeVZyZFdKbExXRndhWE5sY25abGNpMXpaWEoyCmFXTmxMVzVsZEhkdmNtc3RjMmxuYm1WeU1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0MKQVFFQXRJK3pHSXRFR05uL1o2L3RTdWMxZkNzZ2dPeWFoaVU4eVcxVFAvQ0FLWDRRLzNtVzdteXRpUWxzdGlxNApZcStzbllyaUxaQ2o2WDBNaUZWNmp3cTF3aW5JbUNNZnBGY0lSUFNYckw1eGZZcHJBUWFXY2ZPcU1xa2lubllSCjFwRkNhZE95cFZaMUdsOGNNM3pRTmRBOEozVXFDbS9Cc0Nzd2ttcytEMHVueFEwdHlSNHM5RVN2eWhtc2xQUTEKYWVCK0VDMWhlQ3gyTFpTdENoS1QzdU0vZFBvRnV0bndCUDJ5Z3lHWkNPZmVYbXdUZ0s2MzEzbE02WHl3RFlldgpaSGNmNURRckNTUCsvYllNZVVqakZQOElIeEhrOXZETm9TbEw1cW9CM1ZJY1RTRGpnc3V3TGkxbkNEVldURWtPCkcxaFNMNCtHMGthUE1UTmxTakdkdDZzLzhRSURBUUFCbzBJd1FEQU9CZ05WSFE4QkFmOEVCQU1DQXFRd0R3WUQKVlIwVEFRSC9CQVV3QXdFQi96QWRCZ05WSFE0RUZnUVVmMWZaLzBhclU1Q1RPUm5wbC9TYUFaZWNNM3N3RFFZSgpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFEMlQzNlJSV0YxcXJJQ3g4MERKV1V4ZUNQVHVubStaSk1JMk4rZkFpSHBFCkZQK09ZbTlaVndWSW5YdEd5V2J6c2FadjZXM2JVRUxCLzVsQ3RKbGxIS0twK1pqcUxidHBIc3dBbWd1bExMYVEKQ3JnQVVrVUJOVTNPb0Vqb1lTMHo5RHdITW9GRSsyMEJKTWo1QXlzckFSRkZsdFhHdDdmZHd1VDdkbHZ0VDRnRQpUTzJ0QUdSdDRKNHdGUmlNQXpOaUdiV0NHa2FzcHZkMk5raEFzVFpiQTQ4UFJIaWxLTVd0K2NRU283d3FzQ0dpCm5POGxKdjIydUd2V1ZzWlg0Y2MrRDBTL3hicWd3Rk1UOFJ4VVV3S2ZlSFl2NzFmRWhtZ3FPeFVPa2U0WDg3OTUKdE5JME5ZMzVIVWpjWFJVNnVkbU9oZDJIRWFMMDM5ZFBjckRzaE1RSWxxRT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRE1UQ0NBaG1nQXdJQkFnSUhGaDBUMzVLL3RqQU5CZ2txaGtpRzl3MEJBUXNGQURBM01SSXdFQVlEVlFRTApFd2x2Y0dWdWMyaHBablF4SVRBZkJnTlZCQU1UR0d0MVltVXRZWEJwYzJWeWRtVnlMV3hpTFhOcFoyNWxjakFlCkZ3MHlOREEyTVRjeE5qQTJOVEJhRncwek5EQTJNVFV4TmpBMk5UQmFNRGN4RWpBUUJnTlZCQXNUQ1c5d1pXNXoKYUdsbWRERWhNQjhHQTFVRUF4TVlhM1ZpWlMxaGNHbHpaWEoyWlhJdGJHSXRjMmxuYm1WeU1JSUJJakFOQmdrcQpoa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXMzQWxhVnlyT1liT1A2TEF3b3pmR2VSdGJSaXE5NlNYCmtmdHdwUytlUG4xajRuUzRvYmF1VmhPTElKYzJYcTlLVnpGWFVCeEFXNXpVTWc3QVdvYkN6cnRMNElTNUdkNGsKNVZLcW9OV0N1d3A4cTdOb0ZJSE15S0M4dUllOEJuQjg4d3JyVzYyZCt3Rnp4YnlZQll6Sjlpc0xJNUpteVNaVApuOFFpcXQyamxJZklNY0lEZVVTN0NSOFZTL0FiaXhabCsxNVBEanpaZEFpR0JKdWFkNy9tc3RsR1VabWlYUHpUCjNYekZWdEpEWXhxUm9Cb0lTLzQzUVRCcmgyd3VaWWdTVWhmRmtiWVM5c00zeGgrOXNBVmUvVTRVUjhOWGs1RlIKdkNtS1JIZ2F4QjFJT0liUDNMeFRpaU5oazI4ZW9ucHhYdnFXMEtvNEw3b055SjloWTNWR1J3SURBUUFCbzBJdwpRREFPQmdOVkhROEJBZjhFQkFNQ0FxUXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QWRCZ05WSFE0RUZnUVU3bDJBClRtNFRVVXM1bHNhUHhTSXkrZ1crTDNvd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFDWlprWVB0ZXNpdGUxMGMKWmk0Q1lMTFJCSFl6QXhBWlFBYUliSCtIckI4M2dXWnRkTzVzaElhY3Y2ejZPSUVvNnhBZVFJaGpyM05YMDA0SApSY3poOC9mV2ZEMzVuR3lUeTBYZ3V1cE5LQnluSElHenQ1dUxqZXFQVUZxOG9ZU0hoZDExS0RBZlhjbU83Q3YrCjZ5Q1lKdllSTGhJZmtnbFpHUm50dHBwYWl6YnFhVG1QWG5wdXNMNWo5RnNxbEZxc08rOTFYQzhKeUM4RkhkTGgKRmw0TVNQRFJZeGt2aG9zUmh2UC9TQlhJR28zS2Q4eCtZWWpCTThDQVFwNEJSMi91b3FKSEd6Z1NwVmNwWDlpSApPUzA0OExYOElRMXdKcTJlc0lxQUUycFFtS1IreXpkc2RlS0d5UHhaZDRjdGJnL1I5emdNVUsyTVZhL2hDTS93CmZLVkt5azQ9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + server: https://api.kni-qe-69.lab.eng.rdu2.redhat.com:6443 + name: kni-qe-69 +contexts: +- context: + cluster: kni-qe-69 + user: admin + name: admin +current-context: admin +kind: Config +preferences: {} +users: +- name: admin + user: + client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURaekNDQWsrZ0F3SUJBZ0lJSHJqWVlURFVTRzR3RFFZSktvWklodmNOQVFFTEJRQXdOakVTTUJBR0ExVUUKQ3hNSmIzQmxibk5vYVdaME1TQXdIZ1lEVlFRREV4ZGhaRzFwYmkxcmRXSmxZMjl1Wm1sbkxYTnBaMjVsY2pBZQpGdzB5TkRBMk1UY3hOakEyTlRGYUZ3MHpOREEyTVRVeE5qQTNNemxhTURBeEZ6QVZCZ05WQkFvVERuTjVjM1JsCmJUcHRZWE4wWlhKek1SVXdFd1lEVlFRREV3eHplWE4wWlcwNllXUnRhVzR3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUN4N0xOamsyMmFBd1BxRkRPYmM2aDVWRk1OckRJT2JQa1Vub0MxZ3hFRQpIZFNSNUZkQVVoNm50M3lsM1NkWEdWUmcyUUc0RVlRaUpqVGN5KzRST1BXcmY3dVh2d211cm5yblp4M1hXeWluCjN0aGU5K3RDMTd4ZlA3alh5T2xlZm9kRU5lOEJwNnJQdldDTHk3NC9tQlRzcEh6Rnk4cW5POCtRLzRqTE5kb2IKbnNSNUYxVFdoVE00QUQ5Y2lCZHRwS2FXaWNVcU9yNlFTWVE5cWFtYXBScXM1ZzB1TldLMFY4a1RsK1RYWXVvTApnQjdoL3NCVE41QkFYV01ldHdlOUl0YVJrUGhwQUxWbFlmM1Jkem9XSlUvcUFXR0VKeU5zSkZFSHc4UjFMY29QCmZhUVQ2enA5NERpS3RsZ2pJTnNyT3lxRkNWU1EzaFhpR2JZSEw2SHZxNGc1QWdNQkFBR2pmekI5TUE0R0ExVWQKRHdFQi93UUVBd0lGb0RBZEJnTlZIU1VFRmpBVUJnZ3JCZ0VGQlFjREFRWUlLd1lCQlFVSEF3SXdEQVlEVlIwVApBUUgvQkFJd0FEQWRCZ05WSFE0RUZnUVVhMEZnMUxtU1ZRREUzcXQ2OEllSGI5Zi9STlV3SHdZRFZSMGpCQmd3CkZvQVU1L1Z6Wm5NTk1mUUYyZkh0bXZhRk1jWWF6Yzh3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUtrTWtJNXgKcGREdWRiRlAxWWhXU3dPbFpDZlBYY2U2WGVETU1BRHdTb0dhUHppZmk0bHErVXNvbUd0QnM5ZnU1bU5yUXlHQwpYbjZYclgvNDloRENpQ1Q5ZXlpMHlaYjlIVXF2ajdiMlBwZ0lTUnArbVJDc21jdHZKT1NabXp4bmlxUy9jdkx1CjBRaUV0MHdMaEs5cTlEdEwwUGpPc2RTcUhtbXdVLzNlT0toTXJYcC9ydkVvaVZoRmZEcDV2NDFOcWRyZUhnaGUKK1RkN0ZaZTB6VFhMblllSGIzTkl3WXRSL3hWbUptTEVmL1o5WnZ4Rk84YXBDdjBPWTFpdFFJQk5ha010bHhkTgpVMzk1cDk2Q2QrOEg2dDNmUmtXTXQvaFB5YkZKek5wLzhtVEUxbzRPUk01bWR2Y0doZDdGaTdiaVI1Y3ZkWG5kCi8vejNWYW5VbHFSQWxCWT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBc2V5elk1TnRtZ01ENmhRem0zT29lVlJURGF3eURtejVGSjZBdFlNUkJCM1VrZVJYClFGSWVwN2Q4cGQwblZ4bFVZTmtCdUJHRUlpWTAzTXZ1RVRqMXEzKzdsNzhKcnE1NjUyY2QxMXNvcDk3WVh2ZnIKUXRlOFh6KzQxOGpwWG42SFJEWHZBYWVxejcxZ2k4dStQNWdVN0tSOHhjdktwenZQa1ArSXl6WGFHNTdFZVJkVQoxb1V6T0FBL1hJZ1hiYVNtbG9uRktqcStrRW1FUGFtcG1xVWFyT1lOTGpWaXRGZkpFNWZrMTJMcUM0QWU0ZjdBClV6ZVFRRjFqSHJjSHZTTFdrWkQ0YVFDMVpXSDkwWGM2RmlWUDZnRmhoQ2NqYkNSUkI4UEVkUzNLRDMya0UrczYKZmVBNGlyWllJeURiS3pzcWhRbFVrTjRWNGhtMkJ5K2g3NnVJT1FJREFRQUJBb0lCQUNlZThDdWlidXUyOUM0eQpKWFBlZzR2UkxWV0VIUGw5WnRJaW9jTEoxd1kxcGxwK29MZGdFaGVERXF6VTNLZldxaVdPN1lVUjBYelJTVUJKCjRVL1FnVlNaY3lyTmpkaHFYbEFkZEZXNnBRa001TjN4RTJDbExmdC84eWVLUS8yWTY0SlRDRkEwQ0NPT3BtczcKQ2JpYm96MDNPOW5JRWU2L3NPODNHRDA0VnNPRGJtVDBUbWFxT2czV1lpeDlUMVhFemNuLzV6QnJ2aTh3QXdrRgpDU1M2UWZPMWVQSXVnRTJxbWIrL1lTMFBEc1ZWMVNmTkY5TE9wSnFFVFo5R2k1ZzJNU1AwN2Uzdm8xUTJtSDR2CnpIL1N6dW9xd0xsRUh0V1VBZjgwd3RSc3ZZNkFtSEJHbzgwT25GLzByc2M5K3F4eE96VTNYRThpcUVPa09oMysKL3k5Skora0NnWUVBMEhWem15R0hzWEFhL0REWE9WWHZFZ09oUXlsWHNZZHFSNVdMdjUvclAyZ2hhdTF1T0dQWApvSjdobjljSlcvWGtSdkZyWUxVUkRTS1VycmdRdFRwb0NRZUMzRnVyekY3MUdnSElyd2FtSUhvOXlwUm9YU25vCmZ0WlhwL0FmREdma1FUSnJiM3VkTzJQUy9kTWhPb1EyVk5ON3cwTFNIVlJmckl6VGFtYXRQdGNDZ1lFQTJvQ08KdU5rVVhrK1dyUzBJZVAvMHFzMWxsN2JQZjhaSC9aZzVHYkpCVmJWazg0TFpTMjRHU2s0SDVDb3pHMjB6UUxRbwpsblJBMWE1aFBpVFV5cm45TU8weXZQWlRLME9sZDFzemtNa2g5UUdsQkVvam1kbGJLRlhjTTE5OXgxRFdJaU01CnhDTk5kQnV0bDhkeFRETlJMbWtQemI1NGRUS3RqVDdYRG51dzMyOENnWUVBcW93Tkl4UlJvZmZuL0FBeGRYVTYKL08vL1ZhVlRXNmxBYUlTUEt4MjVKODBYMmhXYW9ZUDkvQ2xBeXJieHIwMERrSThmbktWRzZBb3N2cTFVN2hCMAo0VDVGNytjSUxWSmJFUVg0bkVuQ1RMdjJKZkU1V1U5YUtidFBSOVNLY21ubE12bi9MOXhnalNCa2xNblJXOENqCmVzN3phSk1ZdUdvNVJFQ0xEM2dsc1UwQ2dZQmdjemtNN1gzcE41YWFjUE41ZmZxQlh0TkdpZ0xFTTBGWjl0VFYKdS9MTkk1b2hSNVFsa0xha0hCZXRwdGNTZHp5VmhqRVlZTTZ4eEJ6V3NxbGZwNFBWRWc5QWpEY2dOT2NZYmFDdwplNmhLbjJRNUpZVGJoNitPZVlBUENVcmJMWnFvVFFaVnh3T01paDh4alc4OHBMWmtGeXBMdHBVem5xQXZaaHJHCklPRnRid0tCZ1FDSG1yeThSZG1GM2hPVkVjd01Ud1grY1ZUSUJXMG9Ha0dLVWJxUHNXakllTVNDOVdZaHdqaTEKVjFJclZBSEZxaXo2SjJtSDlCUVNtSVhMU1FVRzNIR3Yxd3FKS2s4aWQ4ZmVxdGVMekZmQnJOMjJQa2d5ckE3RQpWYWs2TGlQS2hWYjdKWUpuTWN4dnMrbHRCRVRPMGsvRVNubXVhS2NJekxyb2dLekdpS0t4OGc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= diff --git a/tests/system-tests/internal/cleanup/namespace.go b/tests/system-tests/internal/cleanup/namespace.go deleted file mode 100644 index 55463b2a9..000000000 --- a/tests/system-tests/internal/cleanup/namespace.go +++ /dev/null @@ -1,49 +0,0 @@ -package cleanup - -import ( - "fmt" - "github.com/golang/glog" - "github.com/openshift-kni/eco-goinfra/pkg/clients" - "github.com/openshift-kni/eco-goinfra/pkg/deployment" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "time" -) - -// CleanupNamespace cleanup specific namespace and delete it according to the flag config. -func CleanupNamespace(apiClient *clients.Settings, nsname string, toDelete bool, timeout time.Duration) error { - glog.V(100).Infof("Scaling down namespace %s resources", nsname) - - deleteResources := []string{"deployment", "replicaset", "replicationcontroller", "statefulset"} - - deployments, err := deployment.List(apiClient, nsname, metav1.ListOptions{}) - glog.V(100).Infof("Scaling down deployment resources: %v", deployments) - - if err == nil { - for _, depl := range deployments { - depl, deletionErr := depl.WithReplicas(0).Update() - - if deletionErr != nil { - return fmt.Errorf("failed to delete deployment %s in namespace %s", - depl.Definition.Name, depl.Definition.Namespace) - } - } - glog.V(100).Infof("no active deployments found in namespace %s", nsname) - } - - replicaset, err := replicaset.List(apiClient, nsname, metav1.ListOptions{}) - glog.V(100).Infof("Scaling down replicaset resources: %v", replicaset) - - if err == nil { - for _, depl := range deployments { - depl, deletionErr := depl.WithReplicas(0).Update() - - if deletionErr != nil { - return fmt.Errorf("failed to delete deployment %s in namespace %s", - depl.Definition.Name, depl.Definition.Namespace) - } - } - glog.V(100).Infof("no active deployments found in namespace %s", nsname) - } - - return nil -} diff --git a/tests/system-tests/internal/mirroring/mirror-images.go b/tests/system-tests/internal/mirroring/mirror-images.go index 03f967e3b..cc2135b51 100644 --- a/tests/system-tests/internal/mirroring/mirror-images.go +++ b/tests/system-tests/internal/mirroring/mirror-images.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path/filepath" + "strings" "github.com/golang/glog" "github.com/openshift-kni/eco-goinfra/pkg/clients" @@ -96,9 +97,11 @@ func CopyRegistryAuthLocally(host, user, pass, combinedPullSecretFile string) (s return "", err } - remoteRegistryPullSecretFilePath := filepath.Join(out, combinedPullSecretFile) + remoteUserHomeDir := strings.Trim(out, "\n") + + remoteRegistryPullSecretFilePath := filepath.Join(remoteUserHomeDir, combinedPullSecretFile) localRegistryPullSecretFilePath := filepath.Join("/tmp", combinedPullSecretFile) - remoteDockerDirectoryPath := filepath.Join(out, ".docker") + remoteDockerDirectoryPath := filepath.Join(remoteUserHomeDir, ".docker") localDockerDirectoryPath := filepath.Join(homeDir, ".docker") err = remote.ScpFileFrom( diff --git a/tests/system-tests/internal/ocpcli/ocpcli.go b/tests/system-tests/internal/ocpcli/ocpcli.go index e8ee2c590..6e9a1252c 100644 --- a/tests/system-tests/internal/ocpcli/ocpcli.go +++ b/tests/system-tests/internal/ocpcli/ocpcli.go @@ -75,8 +75,8 @@ func DownloadAndExtractOcBinaryArchive(apiClient *clients.Settings) error { return nil } -// ApplyConfigFile applies config using shell method. -func ApplyConfigFile( +// ApplyConfig applies config using shell method. +func ApplyConfig( templateDir, fileName, destinationDir, @@ -101,6 +101,32 @@ func ApplyConfigFile( return nil } +// CreateConfig creates config using shell method. +func CreateConfig( + templateDir, + fileName, + destinationDir, + finalFileName string, + variablesToReplace map[string]interface{}) error { + err := template.SaveTemplate( + templateDir, fileName, destinationDir, finalFileName, variablesToReplace) + + if err != nil { + return err + } + + cfgFilePath := filepath.Join(destinationDir, finalFileName) + + applyCmd := fmt.Sprintf("oc create -f %s", cfgFilePath) + _, err = shell.ExecuteCmd(applyCmd) + + if err != nil { + return fmt.Errorf("failed to execute %s command due to: %w", applyCmd, err) + } + + return nil +} + // PatchWithNamespace patches the resource using the given patch type, object belongs to the specific namespace // The following patches are exactly the same patch but using different types, 'merge' and 'json' // --type merge -p '{"spec": {"selector": {"app": "frommergepatch"}}}' diff --git a/tests/system-tests/vcore/internal/config-files/clo-instance.yaml b/tests/system-tests/vcore/internal/config-files/clo-instance.yaml deleted file mode 100644 index d4a6f5d32..000000000 --- a/tests/system-tests/vcore/internal/config-files/clo-instance.yaml +++ /dev/null @@ -1,69 +0,0 @@ -apiVersion: logging.openshift.io/v1 -kind: ClusterLogging -metadata: - name: "{{ .ClusterLoggingName }}" - namespace: "{{ .ClusterLoggingNamespace }}" -spec: - collection: - logs: - fluentd: - resources: - limits: - memory: 2Gi - requests: - cpu: 100m - memory: 1Gi - tolerations: - - effect: NoSchedule - key: node-role.kubernetes.io/master - operator: Exists - type: fluentd - curation: - curator: - schedule: 30 * * * * - type: curator - logStore: - elasticsearch: - nodeCount: {{ .NodeCount }} - nodeSelector: - node-role.kubernetes.io/master: '' - redundancyPolicy: SingleRedundancy - resources: - limits: - cpu: 8 - memory: 64Gi - requests: - cpu: 8 - memory: 64Gi - storage: - size: 150Gi - storageClassName: ocs-storagecluster-cephfs - tolerations: - - effect: NoSchedule - key: node-role.kubernetes.io/master - operator: Exists - retentionPolicy: - application: - maxAge: 1d - audit: - maxAge: 7d - infra: - maxAge: 7d - type: elasticsearch - managementState: Managed - visualization: - kibana: - nodeSelector: - node-role.kubernetes.io/master: '' - replicas: 1 - resources: - limits: - memory: 2Gi - requests: - cpu: 1 - memory: 2Gi - tolerations: - - effect: NoSchedule - key: node-role.kubernetes.io/master - operator: Exists - type: kibana diff --git a/tests/system-tests/vcore/internal/config-files/keda-test-app-load-job.yaml b/tests/system-tests/vcore/internal/config-files/keda-test-app-load-job.yaml new file mode 100644 index 000000000..314110890 --- /dev/null +++ b/tests/system-tests/vcore/internal/config-files/keda-test-app-load-job.yaml @@ -0,0 +1,24 @@ +apiVersion: batch/v1 +kind: Job +metadata: + generateName: generate-requests- + namespace: '{{ .KedaWatchNamespace }}' +spec: + template: + spec: + containers: + - image: {{ .AbImageURL }} + name: test + command: ["/bin/sh"] + args: ["-c", "for i in $(seq 1 50);do echo $i;ab -c 5 -n 120 -v 2 http://test-app.{{ .TestNamespace }}.svc/;sleep 1;done"] + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + restartPolicy: Never + activeDeadlineSeconds: 120 + backoffLimit: 2 \ No newline at end of file diff --git a/tests/system-tests/vcore/internal/monitoring/servicemonitor.go b/tests/system-tests/vcore/internal/monitoring/servicemonitor.go new file mode 100644 index 000000000..31a511b3b --- /dev/null +++ b/tests/system-tests/vcore/internal/monitoring/servicemonitor.go @@ -0,0 +1,364 @@ +package monitoring + +import ( + "context" + "fmt" + + monv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + + "github.com/golang/glog" + "github.com/openshift-kni/eco-goinfra/pkg/clients" + "github.com/openshift-kni/eco-goinfra/pkg/msg" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + goclient "sigs.k8s.io/controller-runtime/pkg/client" +) + +// Builder provides a struct for serviceMonitor object from the cluster +// and a serviceMonitor definition. +type Builder struct { + // serviceMonitor definition, used to create the serviceMonitor object. + Definition *monv1.ServiceMonitor + // Created serviceMonitor object. + Object *monv1.ServiceMonitor + // Used to store latest error message upon defining or mutating serviceMonitor definition. + errorMsg string + // api client to interact with the cluster. + apiClient goclient.Client +} + +// NewBuilder creates a new instance of Builder. +func NewBuilder( + apiClient *clients.Settings, name, nsname string) *Builder { + glog.V(100).Infof( + "Initializing new serviceMonitor structure with the following params: "+ + "name: %s, namespace: %s", name, nsname) + + if apiClient == nil { + glog.V(100).Infof("serviceMonitor 'apiClient' cannot be empty") + + return nil + } + + builder := &Builder{ + apiClient: apiClient.Client, + Definition: &monv1.ServiceMonitor{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: nsname, + }, + }, + } + + if name == "" { + glog.V(100).Infof("The name of the serviceMonitor is empty") + + builder.errorMsg = "serviceMonitor 'name' cannot be empty" + + return builder + } + + if nsname == "" { + glog.V(100).Infof("The nsname of the serviceMonitor is empty") + + builder.errorMsg = "serviceMonitor 'nsname' cannot be empty" + + return builder + } + + return builder +} + +// Pull pulls existing serviceMonitor from cluster. +func Pull(apiClient *clients.Settings, + name, nsname string) (*Builder, error) { + glog.V(100).Infof("Pulling existing serviceMonitor name %s in namespace %s from cluster", + name, nsname) + + if apiClient == nil { + glog.V(100).Infof("The apiClient is empty") + + return nil, fmt.Errorf("serviceMonitor 'apiClient' cannot be empty") + } + + builder := Builder{ + apiClient: apiClient.Client, + Definition: &monv1.ServiceMonitor{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: nsname, + }, + }, + } + + if name == "" { + glog.V(100).Infof("The name of the serviceMonitor is empty") + + return nil, fmt.Errorf("serviceMonitor 'name' cannot be empty") + } + + if nsname == "" { + glog.V(100).Infof("The namespace of the serviceMonitor is empty") + + return nil, fmt.Errorf("serviceMonitor 'nsname' cannot be empty") + } + + if !builder.Exists() { + return nil, fmt.Errorf("serviceMonitor object %s does not exist in namespace %s", name, nsname) + } + + builder.Definition = builder.Object + + return &builder, nil +} + +// Get fetches the defined serviceMonitor from the cluster. +func (builder *Builder) Get() (*monv1.ServiceMonitor, error) { + if valid, err := builder.validate(); !valid { + return nil, err + } + + glog.V(100).Infof("Getting serviceMonitor %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + serviceMonitorObj := &monv1.ServiceMonitor{} + err := builder.apiClient.Get(context.TODO(), goclient.ObjectKey{ + Name: builder.Definition.Name, + Namespace: builder.Definition.Namespace, + }, serviceMonitorObj) + + if err != nil { + return nil, err + } + + return serviceMonitorObj, nil +} + +// Create makes a serviceMonitor in the cluster and stores the created object in struct. +func (builder *Builder) Create() (*Builder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Creating the serviceMonitor %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + var err error + if !builder.Exists() { + err = builder.apiClient.Create(context.TODO(), builder.Definition) + if err == nil { + builder.Object = builder.Definition + } + } + + return builder, err +} + +// Delete removes serviceMonitor from a cluster. +func (builder *Builder) Delete() (*Builder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Deleting the serviceMonitor %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + if !builder.Exists() { + glog.V(100).Infof("serviceMonitor %s in namespace %s cannot be deleted"+ + " because it does not exist", + builder.Definition.Name, builder.Definition.Namespace) + + builder.Object = nil + + return builder, nil + } + + err := builder.apiClient.Delete(context.TODO(), builder.Definition) + + if err != nil { + return builder, fmt.Errorf("can not delete serviceMonitor: %w", err) + } + + builder.Object = nil + + return builder, nil +} + +// Exists checks whether the given serviceMonitor exists. +func (builder *Builder) Exists() bool { + if valid, _ := builder.validate(); !valid { + return false + } + + glog.V(100).Infof("Checking if serviceMonitor %s exists in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + var err error + builder.Object, err = builder.Get() + + return err == nil || !k8serrors.IsNotFound(err) +} + +// Update renovates the existing serviceMonitor object with serviceMonitor definition in builder. +func (builder *Builder) Update() (*Builder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Updating serviceMonitor %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + err := builder.apiClient.Update(context.TODO(), builder.Definition) + + if err != nil { + glog.V(100).Infof( + msg.FailToUpdateError("serviceMonitor", builder.Definition.Name, builder.Definition.Namespace)) + + return nil, err + } + + builder.Object = builder.Definition + + return builder, nil +} + +// WithEndpoints sets the serviceMonitor operator's endpoints. +func (builder *Builder) WithEndpoints( + endpoints []monv1.Endpoint) *Builder { + glog.V(100).Infof( + "Adding endpoints to serviceMonitor %s in namespace %s; endpoints %v", + builder.Definition.Name, builder.Definition.Namespace, endpoints) + + if valid, _ := builder.validate(); !valid { + return builder + } + + if len(endpoints) == 0 { + glog.V(100).Infof("'endpoints' argument cannot be empty") + + builder.errorMsg = "'endpoints' argument cannot be empty" + + return builder + } + + builder.Definition.Spec.Endpoints = endpoints + + return builder +} + +// WithLabels redefines the serviceMonitor with labels. +func (builder *Builder) WithLabels(labels map[string]string) *Builder { + if valid, _ := builder.validate(); !valid { + return builder + } + + glog.V(100).Infof("Defining serviceMonitor with labels: %v", labels) + + if len(labels) == 0 { + glog.V(100).Infof("labels can not be empty") + + builder.errorMsg = "labels can not be empty" + + return builder + } + + for key := range labels { + if key == "" { + glog.V(100).Infof("The 'labels' key cannot be empty") + + builder.errorMsg = "can not apply a labels with an empty key" + + return builder + } + } + + builder.Definition.Labels = labels + + return builder +} + +// WithSelector redefines the serviceMonitor with selector. +func (builder *Builder) WithSelector(selector map[string]string) *Builder { + if valid, _ := builder.validate(); !valid { + return builder + } + + glog.V(100).Infof("Defining serviceMonitor with selector: %v", selector) + + if len(selector) == 0 { + glog.V(100).Infof("selector can not be empty") + + builder.errorMsg = "selector can not be empty" + + return builder + } + + for key := range selector { + if key == "" { + glog.V(100).Infof("The 'selector' key cannot be empty") + + builder.errorMsg = "can not apply a selector with an empty key" + + return builder + } + } + + builder.Definition.Spec.Selector.MatchLabels = selector + + return builder +} + +// WithNamespaceSelector redefines the serviceMonitor with namespaceSelector. +func (builder *Builder) WithNamespaceSelector(namespaceSelector []string) *Builder { + if valid, _ := builder.validate(); !valid { + return builder + } + + glog.V(100).Infof("Defining serviceMonitor with namespaceSelector: %v", namespaceSelector) + + if len(namespaceSelector) == 0 { + glog.V(100).Infof("namespaceSelector can not be empty") + + builder.errorMsg = "namespaceSelector can not be empty" + + return builder + } + + builder.Definition.Spec.NamespaceSelector = monv1.NamespaceSelector{ + MatchNames: namespaceSelector, + } + + return builder +} + +// validate will check that the builder and builder definition are properly initialized before +// accessing any member fields. +func (builder *Builder) validate() (bool, error) { + resourceCRD := "ServiceMonitor" + + if builder == nil { + glog.V(100).Infof("The %s builder is uninitialized", resourceCRD) + + return false, fmt.Errorf("error: received nil %s builder", resourceCRD) + } + + if builder.Definition == nil { + glog.V(100).Infof("The %s is undefined", resourceCRD) + + return false, fmt.Errorf(msg.UndefinedCrdObjectErrString(resourceCRD)) + } + + if builder.apiClient == nil { + glog.V(100).Infof("The %s builder apiclient is nil", resourceCRD) + + return false, fmt.Errorf("%s builder cannot have nil apiClient", resourceCRD) + } + + if builder.errorMsg != "" { + glog.V(100).Infof("The %s builder has error message: %s", resourceCRD, builder.errorMsg) + + return false, fmt.Errorf(builder.errorMsg) + } + + return true, nil +} diff --git a/tests/system-tests/vcore/internal/vcorecommon/esk-clo-operator.go b/tests/system-tests/vcore/internal/vcorecommon/esk-clo-operator.go index f426288fd..9e260e9b4 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/esk-clo-operator.go +++ b/tests/system-tests/vcore/internal/vcorecommon/esk-clo-operator.go @@ -102,7 +102,7 @@ func CreateCLOInstance(ctx SpecContext) { templateDir := filepath.Join(workingDir, vcoreparams.TemplateFilesFolder) - err = ocpcli.ApplyConfigFile( + err = ocpcli.ApplyConfig( templateDir, clusterLoggingTemplateName, destinationDirectoryPath, diff --git a/tests/system-tests/vcore/internal/vcorecommon/keda-validation.go b/tests/system-tests/vcore/internal/vcorecommon/keda-validation.go index 9f5ef3dff..d2a41c5d6 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/keda-validation.go +++ b/tests/system-tests/vcore/internal/vcorecommon/keda-validation.go @@ -1,33 +1,50 @@ package vcorecommon import ( + "context" "fmt" + "github.com/openshift-kni/eco-goinfra/pkg/reportxml" + "github.com/openshift-kni/eco-goinfra/pkg/secret" + "k8s.io/apimachinery/pkg/util/wait" + "os" + "path/filepath" + "time" + kedav1alpha1 "github.com/kedacore/keda-olm-operator/apis/keda/v1alpha1" + kedav2v1alpha1 "github.com/kedacore/keda/v2/apis/keda/v1alpha1" "github.com/openshift-kni/eco-goinfra/pkg/configmap" + "github.com/openshift-kni/eco-goinfra/pkg/deployment" "github.com/openshift-kni/eco-goinfra/pkg/keda" + "github.com/openshift-kni/eco-goinfra/pkg/namespace" + "github.com/openshift-kni/eco-goinfra/pkg/rbac" + "github.com/openshift-kni/eco-goinfra/pkg/service" + "github.com/openshift-kni/eco-goinfra/pkg/serviceaccount" "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/mirroring" + "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/ocpcli" "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/platform" - "os" - "path/filepath" - "time" + "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/monitoring" + monv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/util/intstr" "github.com/golang/glog" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/apiobjectshelper" - "github.com/openshift-kni/eco-goinfra/pkg/reportxml" . "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreinittools" "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreparams" ) const ( - kedaScaleObjectName = "prometheus-scaledobject" + kedaScaledObjectName = "prometheus-scaledobject" configmapName = "cluster-monitoring-config" configmapNamespace = "openshift-monitoring" maxReplicaCount = 8 - testAppServicemonitorName = "keda-testing-sm" - serviceaccountName = "thanos" + testAppServiceMonitorName = "keda-testing-sm" + serviceAccountName = "thanos" + saTokenName = "thanos-secret" triggerAuthName = "keda-trigger-auth-prometheus" metricsReaderName = "thanos-metrics-reader" @@ -40,6 +57,40 @@ const ( abImageTag = "latest" ) +// VerifyKedaSuite container that contains tests for Keda verification. +func VerifyKedaSuite() { + Describe( + "Keda validation", + Label(vcoreparams.LabelVCoreOperators), func() { + BeforeAll(func() { + By(fmt.Sprintf("Asserting %s folder exists", vcoreparams.ConfigurationFolderName)) + + homeDir, err := os.UserHomeDir() + Expect(err).To(BeNil(), fmt.Sprint(err)) + + vcoreConfigsFolder := filepath.Join(homeDir, vcoreparams.ConfigurationFolderName) + + glog.V(vcoreparams.VCoreLogLevel).Infof("vcoreConfigsFolder: %s", vcoreConfigsFolder) + + if err := os.Mkdir(vcoreConfigsFolder, 0755); os.IsExist(err) { + glog.V(vcoreparams.VCoreLogLevel).Infof("%s folder already exists", vcoreConfigsFolder) + } + }) + + It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.KedaNamespace), + Label("keda"), VerifyKedaNamespaceExists) + + It("Verifies Keda operator deployment succeeded", + Label("keda"), reportxml.ID("65001"), VerifyKedaDeployment) + + It("Verifies KedaController instance created successfully", + Label("keda"), reportxml.ID("65004"), VerifyKedaControllerDeployment) + + It("Verifies ScaleObject instance created successfully", + Label("keda"), reportxml.ID("65007"), VerifyScaleObjectDeployment) + }) +} + // VerifyKedaNamespaceExists asserts namespace for NMState operator exists. func VerifyKedaNamespaceExists(ctx SpecContext) { err := apiobjectshelper.VerifyNamespaceExists(APIClient, vcoreparams.KedaNamespace, time.Second) @@ -63,13 +114,14 @@ func VerifyKedaDeployment(ctx SpecContext) { func VerifyKedaControllerDeployment(ctx SpecContext) { glog.V(vcoreparams.VCoreLogLevel).Infof("Verify kedaController instance exists") - kedaControllerBuilder := keda.NewKedaControllerBuilder( + kedaControllerBuilder := keda.NewControllerBuilder( APIClient, vcoreparams.KedaControllerName, vcoreparams.KedaNamespace) if !kedaControllerBuilder.Exists() { var err error + admissionWebhooks := kedav1alpha1.KedaAdmissionWebhooksSpec{ LogLevel: "info", LogEncoder: "console", @@ -88,8 +140,8 @@ func VerifyKedaControllerDeployment(ctx SpecContext) { WithWatchNamespace(vcoreparams.KedaWatchNamespace). Create() Expect(err).ToNot(HaveOccurred(), - fmt.Sprintf("Failed to create kedaController instance %q in namespace %q due to: %v", - vcoreparams.KedaControllerName, vcoreparams.KedaNamespace, err.Error())) + fmt.Sprintf("Failed to create kedaController instance %q in namespace %q due to: %w", + vcoreparams.KedaControllerName, vcoreparams.KedaNamespace, err)) Expect(kedaControllerBuilder.Exists()).To(Equal(true), fmt.Sprintf( "no kedaController instance %s was found in the namespace %s", vcoreparams.KedaControllerName, vcoreparams.KedaNamespace)) @@ -97,8 +149,11 @@ func VerifyKedaControllerDeployment(ctx SpecContext) { } // func VerifyKedaControllerDeployment (ctx SpecContext) // VerifyScaleObjectDeployment assert that scaleObject instance created successfully. +// +//nolint:funlen func VerifyScaleObjectDeployment(ctx SpecContext) { glog.V(vcoreparams.VCoreLogLevel).Info("Verify monitoring status") + var err error configMapBuilder := configmap.NewBuilder(APIClient, configmapName, configmapNamespace) @@ -108,80 +163,245 @@ func VerifyScaleObjectDeployment(ctx SpecContext) { WithData(map[string]string{"config.yaml": "enableUserWorkload: true"}).Create() Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("Failed to create configmap %q in namespace %q due to: %v", - configmapName, configmapNamespace, err.Error())) + configmapName, configmapNamespace, err)) Expect(configMapBuilder.Exists()).To(Equal(true), fmt.Sprintf( "no configmap %s was found in the namespace %s", configmapName, configmapNamespace)) } glog.V(vcoreparams.VCoreLogLevel).Info("Deploy application that exposes Prometheus metrics") - namespace - - glog.V(vcoreparams.VCoreLogLevel).Infof("Verify scaleObject instance deployment and functionality") - scaleObjectBuilder := keda.NewScaledObjectBuilder(APIClient, kedaScaleObjectName, vcoreparams.KedaWatchNamespace) - if !scaleObjectBuilder.Exists() { - var err error - admissionWebhooks := kedav1alpha1.KedaAdmissionWebhooksSpec{ - LogLevel: "info", - LogEncoder: "console", - } - operator := kedav1alpha1.KedaOperatorSpec{ - LogLevel: "info", - LogEncoder: "console", - } - metricsServer := kedav1alpha1.KedaMetricsServerSpec{ - LogLevel: "0", - } + watchNamespace := namespace.NewBuilder(APIClient, vcoreparams.KedaWatchNamespace) + if watchNamespace.Exists() { + err = watchNamespace.Delete() + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("Failed to delete watch namespace %s due to: %v", + vcoreparams.KedaWatchNamespace, err)) + + err := wait.PollUntilContextTimeout( + context.TODO(), + time.Second, + time.Second*30, + true, + func(ctx context.Context) (bool, error) { + isExists := watchNamespace.Exists() + + if !isExists { + return true, nil + } - scaleObjectBuilder, err = scaleObjectBuilder.WithAdmissionWebhooks(admissionWebhooks). - WithOperator(operator). - WithMetricsServer(metricsServer). - WithWatchNamespace(vcoreparams.KedaWatchNamespace). - Create() + return false, nil + }) Expect(err).ToNot(HaveOccurred(), - fmt.Sprintf("Failed to create kedaController instance %q in namespace %q due to: %v", - vcoreparams.KedaControllerName, vcoreparams.KedaNamespace, err.Error())) - Expect(scaleObjectBuilder.Exists()).To(Equal(true), fmt.Sprintf( - "no kedaController instance %s was found in the namespace %s", - vcoreparams.KedaControllerName, vcoreparams.KedaNamespace)) + fmt.Sprintf("Failed to delete watch namespace %s due to: %v", + vcoreparams.KedaWatchNamespace, err)) } -} // func VerifyKedaControllerDeployment (ctx SpecContext) -// VerifyKedaSuite container that contains tests for Keda verification. -func VerifyKedaSuite() { - Describe( - "Keda validation", - Label(vcoreparams.LabelVCoreOperators), func() { - BeforeAll(func() { - By(fmt.Sprintf("Asserting %s folder exists", vcoreparams.ConfigurationFolderName)) + Expect(insureNamespaceExists(vcoreparams.KedaWatchNamespace)).To(Equal(true), + fmt.Sprintf("failed to create namespace %s", vcoreparams.KedaWatchNamespace)) - homeDir, err := os.UserHomeDir() - Expect(err).To(BeNil(), fmt.Sprint(err)) + glog.V(vcoreparams.VCoreLogLevel).Infof("Create test application deployment %s in namespace %s", + vcoreparams.KedaWatchAppName, vcoreparams.KedaWatchNamespace) - vcoreConfigsFolder := filepath.Join(homeDir, vcoreparams.ConfigurationFolderName) + prometeusImageURL, err := getImageURL(prometheusOriginMirrorURL, prometheusImageName, prometheusImageTag) + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("Failed to generate prometheus image URL for %s/%s:%s due to: %v", + prometheusOriginMirrorURL, prometheusImageName, prometheusImageTag, err)) + + falseVar := false + trueVar := true + securityContext := corev1.SecurityContext{ + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{"ALL"}, + }, + RunAsNonRoot: &trueVar, + AllowPrivilegeEscalation: &falseVar, + SeccompProfile: &corev1.SeccompProfile{ + Type: "RuntimeDefault", + }, + } - glog.V(vcoreparams.VCoreLogLevel).Infof("vcoreConfigsFolder: %s", vcoreConfigsFolder) + appConteiner := corev1.Container{ + Name: "prom-test-app", + Image: prometeusImageURL, + ImagePullPolicy: "IfNotPresent", + SecurityContext: &securityContext, + } - if err := os.Mkdir(vcoreConfigsFolder, 0755); os.IsExist(err) { - glog.V(vcoreparams.VCoreLogLevel).Infof("%s folder already exists", vcoreConfigsFolder) - } - }) + _, err = deployment.NewBuilder(APIClient, + vcoreparams.KedaWatchAppName, + vcoreparams.KedaWatchNamespace, + map[string]string{"app": vcoreparams.KedaWatchAppName, "type": "keda-testing"}, + &appConteiner, + ).WithReplicas(int32(1)).Create() + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("Failed to create test application %s in namespace %s due to: %v", + vcoreparams.KedaWatchAppName, vcoreparams.KedaWatchNamespace, err)) + + glog.V(vcoreparams.VCoreLogLevel).Infof("Create test application Service %s in namespace %s", + vcoreparams.KedaWatchAppName, vcoreparams.KedaWatchNamespace) + + _, err = service.NewBuilder(APIClient, + vcoreparams.KedaWatchAppName, + vcoreparams.KedaWatchNamespace, + map[string]string{"app": vcoreparams.KedaWatchAppName}, + corev1.ServicePort{ + Name: "http", + Protocol: "TCP", + Port: 80, + TargetPort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: int32(8080), + }, + }, + ).WithAnnotation(map[string]string{"prometheus.io/scrape": "true"}).Create() + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("Failed to create service %s in namespace %s due to: %v", + vcoreparams.KedaWatchAppName, vcoreparams.KedaWatchNamespace, err)) - It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.KedaNamespace), - Label("keda"), VerifyKedaNamespaceExists) + glog.V(vcoreparams.VCoreLogLevel).Infof("Create ServiceMonitor %s in namespace %s", + testAppServiceMonitorName, vcoreparams.KedaWatchNamespace) - It("Verifies Keda operator deployment succeeded", - Label("keda"), reportxml.ID("65001"), VerifyKedaDeployment) + endpoints := []monv1.Endpoint{{ + Port: "http", + Scheme: "http", + }} - It("Verifies KedaController instance created successfully", - Label("keda"), reportxml.ID("65004"), VerifyKedaControllerDeployment) + _, err = monitoring.NewBuilder(APIClient, + testAppServiceMonitorName, + vcoreparams.KedaWatchNamespace).WithEndpoints(endpoints). + WithSelector(map[string]string{"app": "vcoreparams.KedaWatchAppName"}).Create() + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("Failed to create serviceMonitor %s in namespace %s due to: %v", + testAppServiceMonitorName, vcoreparams.KedaWatchNamespace, err)) - It("Verifies ScaleObject instance created successfully", - Label("keda"), reportxml.ID("65007"), VerifyScaleObjectDeployment) - }) -} + glog.V(vcoreparams.VCoreLogLevel).Infof("Create test application ServiceAccount %s in namespace %s "+ + "and locate assigned token", + vcoreparams.KedaWatchAppName, vcoreparams.KedaWatchNamespace) + + _, err = serviceaccount.NewBuilder(APIClient, + serviceAccountName, vcoreparams.KedaWatchNamespace).Create() + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("Failed to create serviceAccount %s in namespace %s due to: %v", + serviceAccountName, vcoreparams.KedaWatchNamespace, err)) + + _, err = secret.NewBuilder(APIClient, + saTokenName, + vcoreparams.KedaWatchNamespace, + corev1.SecretTypeServiceAccountToken). + WithAnnotations(map[string]string{"kubernetes.io/service-account.name": serviceAccountName}).Create() + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("Failed to create token assigned to the serviceAccount %s in namespace %s due to: %v", + serviceAccountName, vcoreparams.KedaWatchNamespace, err)) + + glog.V(vcoreparams.VCoreLogLevel). + Infof("Define TriggerAuthentication %s with the Service Account's token %s in namespace %s", + triggerAuthName, vcoreparams.KedaWatchNamespace, saTokenName) + + secretTargetRef := []kedav2v1alpha1.AuthSecretTargetRef{{ + Parameter: "bearerToken", + Name: saTokenName, + Key: "token", + }, { + Parameter: "ca", + Name: saTokenName, + Key: "ca.crt", + }} + + _, err = keda.NewTriggerAuthenticationBuilder(APIClient, + triggerAuthName, + vcoreparams.KedaWatchNamespace).WithSecretTargetRef(secretTargetRef).Create() + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("Failed to create TriggerAuthentication %s with the Service Account's token %s "+ + "in namespace %s due to: %v", + triggerAuthName, vcoreparams.KedaWatchNamespace, saTokenName, err)) -func getImageUrl(repository, name, tag string) (string, error) { + glog.V(vcoreparams.VCoreLogLevel).Infof("Create a role %s for reading metric from Thanos in namespace %s", + metricsReaderName, vcoreparams.KedaWatchNamespace) + + roleRule1 := rbacv1.PolicyRule{ + APIGroups: []string{""}, + Resources: []string{"pods"}, + Verbs: []string{"get"}, + } + roleRule2 := rbacv1.PolicyRule{ + APIGroups: []string{"metrics.k8s.io"}, + Resources: []string{"pods", "nodes"}, + Verbs: []string{"get", "list", "watch"}, + } + + _, err = rbac.NewRoleBuilder(APIClient, metricsReaderName, vcoreparams.KedaWatchNamespace, roleRule1). + WithRules([]rbacv1.PolicyRule{roleRule2}).Create() + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("Failed to create a role %s for reading metric from Thanos in namespace %s due to: %v", + metricsReaderName, vcoreparams.KedaWatchNamespace, err)) + + glog.V(vcoreparams.VCoreLogLevel).Infof("Define scaledObject instance %s in namespace %s", + kedaScaledObjectName, vcoreparams.KedaWatchNamespace) + + scaledObjectBuilder := keda.NewScaledObjectBuilder(APIClient, kedaScaledObjectName, vcoreparams.KedaWatchNamespace) + + scaleTargetRef := kedav2v1alpha1.ScaleTarget{ + Name: vcoreparams.KedaWatchAppName, + } + + scaleTriggers := []kedav2v1alpha1.ScaleTriggers{{ + Type: "prometheus", + Metadata: map[string]string{ + "serverAddress": "https://thanos-querier.openshift-monitoring.svc.cluster.local:9092", + "namespace": vcoreparams.KedaWatchNamespace, + "metricName": "http_requests_total", + "threshold": "5", + "query": "sum(rate(http_requests_total{job=\"test-app\"}[1m]))", + "authModes": "bearer", + }, + AuthenticationRef: &kedav2v1alpha1.AuthenticationRef{ + Name: triggerAuthName, + Kind: "TriggerAuthentication", + }, + }} + + _, err = scaledObjectBuilder.WithScaleTargetRef(scaleTargetRef). + WithMinReplicaCount(int32(1)). + WithMaxReplicaCount(int32(8)). + WithPollingInterval(int32(5)). + WithCooldownPeriod(int32(10)). + WithTriggers(scaleTriggers).Create() + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("Failed to create scaledObject instance %s in namespace %s due to: %v", + kedaScaledObjectName, vcoreparams.KedaWatchNamespace, err)) + + glog.V(vcoreparams.VCoreLogLevel).Info("Generate requests to test the application autoscaling") + + abImageURL, err := getImageURL(abOriginMirrorURL, abImageName, abImageTag) + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("Failed to generate prometheus image URL for %s/%s:%s due to: %v", + prometheusOriginMirrorURL, prometheusImageName, prometheusImageTag, err)) + + appLoadJobTemplateName := "keda-test-app-load-job.yaml" + varsToReplace := make(map[string]interface{}) + varsToReplace["KedaWatchNamespace"] = vcoreparams.KedaWatchNamespace + varsToReplace["TestNamespace"] = vcoreparams.KedaWatchNamespace + varsToReplace["AbImageURL"] = abImageURL + homeDir, err := os.UserHomeDir() + Expect(err).ToNot(HaveOccurred(), "user home directory not found; %s", err) + + destinationDirectoryPath := filepath.Join(homeDir, vcoreparams.ConfigurationFolderName) + + workingDir, err := os.Getwd() + Expect(err).ToNot(HaveOccurred(), err) + + templateDir := filepath.Join(workingDir, vcoreparams.TemplateFilesFolder) + + err = ocpcli.CreateConfig( + templateDir, + appLoadJobTemplateName, + destinationDirectoryPath, + appLoadJobTemplateName, + varsToReplace) + Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("failed to create load job due to %v", err)) +} // func VerifyKedaControllerDeployment (ctx SpecContext) + +func getImageURL(repository, name, tag string) (string, error) { imageURL := fmt.Sprintf("%s/%s", repository, name) isDisconnected, err := platform.IsDisconnectedDeployment(APIClient) @@ -208,10 +428,50 @@ func getImageUrl(repository, name, tag string) (string, error) { VCoreConfig.RegistryRepository) if err != nil { - return "", fmt.Errorf("failed to mirror image %s:%s locally due to %v", - imageURL, tag, err) + return "", fmt.Errorf("failed to mirror image %s:%s locally due to %w", + name, tag, err) } } return imageURL, nil } + +func insureNamespaceExists(nsName string) bool { + glog.V(vcoreparams.VCoreLogLevel).Infof("Insure namespace %q exists", nsName) + + createNs := namespace.NewBuilder(APIClient, nsName) + + if !createNs.Exists() { + + createNs, err := createNs.Create() + + if err != nil { + glog.V(vcoreparams.VCoreLogLevel).Infof("Error creating namespace %q: %v", nsName, err) + + return false + } + + err = wait.PollUntilContextTimeout( + context.TODO(), + time.Second, + 3*time.Second, + true, + func(ctx context.Context) (bool, error) { + if !createNs.Exists() { + glog.V(vcoreparams.VCoreLogLevel).Infof("Error creating namespace %q", nsName) + + return false, nil + } + + glog.V(vcoreparams.VCoreLogLevel).Infof("Created namespace %q", createNs.Definition.Name) + + return true, nil + }) + + if err != nil { + return false + } + } + + return true +} diff --git a/tests/system-tests/vcore/internal/vcorecommon/post-deployment-config.go b/tests/system-tests/vcore/internal/vcorecommon/post-deployment-config.go index 381b21b91..3c96884b4 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/post-deployment-config.go +++ b/tests/system-tests/vcore/internal/vcorecommon/post-deployment-config.go @@ -150,7 +150,7 @@ func VerifySCTPModuleActivation(ctx SpecContext) { templateDir := filepath.Join(workingDir, vcoreparams.TemplateFilesFolder) - err = ocpcli.ApplyConfigFile( + err = ocpcli.ApplyConfig( templateDir, sctpModuleTemplateName, destinationDirectoryPath, diff --git a/tests/system-tests/vcore/internal/vcorecommon/smo-validation.go b/tests/system-tests/vcore/internal/vcorecommon/smo-validation.go index 4ec384658..b128ab3ba 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/smo-validation.go +++ b/tests/system-tests/vcore/internal/vcorecommon/smo-validation.go @@ -146,7 +146,7 @@ func VerifyServiceMeshConfig(ctx SpecContext) { varsToReplace["ControlPlaneName"] = "basic" varsToReplace["ControlPlaneNamespace"] = vcoreparams.IstioNamespace - err = ocpcli.ApplyConfigFile( + err = ocpcli.ApplyConfig( templateDir, smoCpTemplateName, destinationDirectoryPath, diff --git a/tests/system-tests/vcore/internal/vcorecommon/sriov-validation.go b/tests/system-tests/vcore/internal/vcorecommon/sriov-validation.go index 2f97b0079..0c6e1f067 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/sriov-validation.go +++ b/tests/system-tests/vcore/internal/vcorecommon/sriov-validation.go @@ -182,12 +182,12 @@ func VerifySRIOVSuite() { "SR-IOV Operator deployment and configuration validation", Label(vcoreparams.LabelVCoreOperators), func() { It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.SRIOVNamespace), - Label("debug"), VerifySRIOVNamespaceExists) + Label("sriov"), VerifySRIOVNamespaceExists) It("Verifies SR-IOV Operator deployment succeeded", - Label("debug"), reportxml.ID("60041"), VerifySRIOVDeployment) + Label("sriov"), reportxml.ID("60041"), VerifySRIOVDeployment) It("Verifies SR-IOV configuration procedure succeeded", - Label("debug"), reportxml.ID("60088"), VerifySRIOVConfig) + Label("sriov"), reportxml.ID("60088"), VerifySRIOVConfig) }) } diff --git a/tests/system-tests/vcore/internal/vcoreparams/const.go b/tests/system-tests/vcore/internal/vcoreparams/const.go index 8d0152670..79390791b 100644 --- a/tests/system-tests/vcore/internal/vcoreparams/const.go +++ b/tests/system-tests/vcore/internal/vcoreparams/const.go @@ -181,6 +181,9 @@ const ( // KedaNamespace is a keda operator namespace. KedaNamespace = "openshift-keda" + // KedaWatchAppName is a keda watch application name. + KedaWatchAppName = "test-app" + // KedaWatchNamespace is a keda watch namespace name. KedaWatchNamespace = "test-appspace" From 94c48770473ef3212839f0d57b3c1f423ca2fb77 Mon Sep 17 00:00:00 2001 From: Elena German Date: Sat, 22 Jun 2024 13:14:58 -0400 Subject: [PATCH 4/5] vCore: keda test suite --- .../config-files/keda-rolebinding.yaml | 13 + .../config-files/keda-test-app-load-job.yaml | 2 +- .../internal/monitoring/servicemonitor.go | 364 ------------------ .../internal/vcorecommon/cgroup-operator.go | 96 ++--- .../internal/vcorecommon/esk-clo-operator.go | 49 +-- .../vcore/internal/vcorecommon/helm.go | 53 +-- .../initial-platform-deployment.go | 71 ++-- .../internal/vcorecommon/keda-validation.go | 156 +++++--- .../vcorecommon/local-storage-operator.go | 26 +- .../internal/vcorecommon/metallb-operator.go | 54 +-- .../vcorecommon/nmstate-validation.go | 41 +- .../vcorecommon/node-tuning-operator.go | 64 +-- .../vcore/internal/vcorecommon/odf.go | 35 +- .../vcorecommon/post-deployment-config.go | 77 ++-- .../vcore/internal/vcorecommon/redis.go | 49 +-- .../internal/vcorecommon/smo-validation.go | 95 ++--- .../internal/vcorecommon/sriov-validation.go | 35 +- 17 files changed, 492 insertions(+), 788 deletions(-) create mode 100644 tests/system-tests/vcore/internal/config-files/keda-rolebinding.yaml delete mode 100644 tests/system-tests/vcore/internal/monitoring/servicemonitor.go diff --git a/tests/system-tests/vcore/internal/config-files/keda-rolebinding.yaml b/tests/system-tests/vcore/internal/config-files/keda-rolebinding.yaml new file mode 100644 index 000000000..94cc48cd1 --- /dev/null +++ b/tests/system-tests/vcore/internal/config-files/keda-rolebinding.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ .RoleBindingName }} + namespace: {{ .RoleBindingNamespace }} +subjects: +- kind: ServiceAccount + name: {{ .ServiceAccountName }} +roleRef: + kind: Role + name: {{ .RoleName }} + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/tests/system-tests/vcore/internal/config-files/keda-test-app-load-job.yaml b/tests/system-tests/vcore/internal/config-files/keda-test-app-load-job.yaml index 314110890..2748dea14 100644 --- a/tests/system-tests/vcore/internal/config-files/keda-test-app-load-job.yaml +++ b/tests/system-tests/vcore/internal/config-files/keda-test-app-load-job.yaml @@ -10,7 +10,7 @@ spec: - image: {{ .AbImageURL }} name: test command: ["/bin/sh"] - args: ["-c", "for i in $(seq 1 50);do echo $i;ab -c 5 -n 120 -v 2 http://test-app.{{ .TestNamespace }}.svc/;sleep 1;done"] + args: ["-c", "for i in $(seq 1 100);do echo $i;ab -c 5 -n 120 -v 2 http://test-app.{{ .TestNamespace }}.svc/;sleep 1;done"] securityContext: allowPrivilegeEscalation: false runAsNonRoot: true diff --git a/tests/system-tests/vcore/internal/monitoring/servicemonitor.go b/tests/system-tests/vcore/internal/monitoring/servicemonitor.go deleted file mode 100644 index 31a511b3b..000000000 --- a/tests/system-tests/vcore/internal/monitoring/servicemonitor.go +++ /dev/null @@ -1,364 +0,0 @@ -package monitoring - -import ( - "context" - "fmt" - - monv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" - - "github.com/golang/glog" - "github.com/openshift-kni/eco-goinfra/pkg/clients" - "github.com/openshift-kni/eco-goinfra/pkg/msg" - k8serrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - goclient "sigs.k8s.io/controller-runtime/pkg/client" -) - -// Builder provides a struct for serviceMonitor object from the cluster -// and a serviceMonitor definition. -type Builder struct { - // serviceMonitor definition, used to create the serviceMonitor object. - Definition *monv1.ServiceMonitor - // Created serviceMonitor object. - Object *monv1.ServiceMonitor - // Used to store latest error message upon defining or mutating serviceMonitor definition. - errorMsg string - // api client to interact with the cluster. - apiClient goclient.Client -} - -// NewBuilder creates a new instance of Builder. -func NewBuilder( - apiClient *clients.Settings, name, nsname string) *Builder { - glog.V(100).Infof( - "Initializing new serviceMonitor structure with the following params: "+ - "name: %s, namespace: %s", name, nsname) - - if apiClient == nil { - glog.V(100).Infof("serviceMonitor 'apiClient' cannot be empty") - - return nil - } - - builder := &Builder{ - apiClient: apiClient.Client, - Definition: &monv1.ServiceMonitor{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: nsname, - }, - }, - } - - if name == "" { - glog.V(100).Infof("The name of the serviceMonitor is empty") - - builder.errorMsg = "serviceMonitor 'name' cannot be empty" - - return builder - } - - if nsname == "" { - glog.V(100).Infof("The nsname of the serviceMonitor is empty") - - builder.errorMsg = "serviceMonitor 'nsname' cannot be empty" - - return builder - } - - return builder -} - -// Pull pulls existing serviceMonitor from cluster. -func Pull(apiClient *clients.Settings, - name, nsname string) (*Builder, error) { - glog.V(100).Infof("Pulling existing serviceMonitor name %s in namespace %s from cluster", - name, nsname) - - if apiClient == nil { - glog.V(100).Infof("The apiClient is empty") - - return nil, fmt.Errorf("serviceMonitor 'apiClient' cannot be empty") - } - - builder := Builder{ - apiClient: apiClient.Client, - Definition: &monv1.ServiceMonitor{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: nsname, - }, - }, - } - - if name == "" { - glog.V(100).Infof("The name of the serviceMonitor is empty") - - return nil, fmt.Errorf("serviceMonitor 'name' cannot be empty") - } - - if nsname == "" { - glog.V(100).Infof("The namespace of the serviceMonitor is empty") - - return nil, fmt.Errorf("serviceMonitor 'nsname' cannot be empty") - } - - if !builder.Exists() { - return nil, fmt.Errorf("serviceMonitor object %s does not exist in namespace %s", name, nsname) - } - - builder.Definition = builder.Object - - return &builder, nil -} - -// Get fetches the defined serviceMonitor from the cluster. -func (builder *Builder) Get() (*monv1.ServiceMonitor, error) { - if valid, err := builder.validate(); !valid { - return nil, err - } - - glog.V(100).Infof("Getting serviceMonitor %s in namespace %s", - builder.Definition.Name, builder.Definition.Namespace) - - serviceMonitorObj := &monv1.ServiceMonitor{} - err := builder.apiClient.Get(context.TODO(), goclient.ObjectKey{ - Name: builder.Definition.Name, - Namespace: builder.Definition.Namespace, - }, serviceMonitorObj) - - if err != nil { - return nil, err - } - - return serviceMonitorObj, nil -} - -// Create makes a serviceMonitor in the cluster and stores the created object in struct. -func (builder *Builder) Create() (*Builder, error) { - if valid, err := builder.validate(); !valid { - return builder, err - } - - glog.V(100).Infof("Creating the serviceMonitor %s in namespace %s", - builder.Definition.Name, builder.Definition.Namespace) - - var err error - if !builder.Exists() { - err = builder.apiClient.Create(context.TODO(), builder.Definition) - if err == nil { - builder.Object = builder.Definition - } - } - - return builder, err -} - -// Delete removes serviceMonitor from a cluster. -func (builder *Builder) Delete() (*Builder, error) { - if valid, err := builder.validate(); !valid { - return builder, err - } - - glog.V(100).Infof("Deleting the serviceMonitor %s in namespace %s", - builder.Definition.Name, builder.Definition.Namespace) - - if !builder.Exists() { - glog.V(100).Infof("serviceMonitor %s in namespace %s cannot be deleted"+ - " because it does not exist", - builder.Definition.Name, builder.Definition.Namespace) - - builder.Object = nil - - return builder, nil - } - - err := builder.apiClient.Delete(context.TODO(), builder.Definition) - - if err != nil { - return builder, fmt.Errorf("can not delete serviceMonitor: %w", err) - } - - builder.Object = nil - - return builder, nil -} - -// Exists checks whether the given serviceMonitor exists. -func (builder *Builder) Exists() bool { - if valid, _ := builder.validate(); !valid { - return false - } - - glog.V(100).Infof("Checking if serviceMonitor %s exists in namespace %s", - builder.Definition.Name, builder.Definition.Namespace) - - var err error - builder.Object, err = builder.Get() - - return err == nil || !k8serrors.IsNotFound(err) -} - -// Update renovates the existing serviceMonitor object with serviceMonitor definition in builder. -func (builder *Builder) Update() (*Builder, error) { - if valid, err := builder.validate(); !valid { - return builder, err - } - - glog.V(100).Infof("Updating serviceMonitor %s in namespace %s", - builder.Definition.Name, builder.Definition.Namespace) - - err := builder.apiClient.Update(context.TODO(), builder.Definition) - - if err != nil { - glog.V(100).Infof( - msg.FailToUpdateError("serviceMonitor", builder.Definition.Name, builder.Definition.Namespace)) - - return nil, err - } - - builder.Object = builder.Definition - - return builder, nil -} - -// WithEndpoints sets the serviceMonitor operator's endpoints. -func (builder *Builder) WithEndpoints( - endpoints []monv1.Endpoint) *Builder { - glog.V(100).Infof( - "Adding endpoints to serviceMonitor %s in namespace %s; endpoints %v", - builder.Definition.Name, builder.Definition.Namespace, endpoints) - - if valid, _ := builder.validate(); !valid { - return builder - } - - if len(endpoints) == 0 { - glog.V(100).Infof("'endpoints' argument cannot be empty") - - builder.errorMsg = "'endpoints' argument cannot be empty" - - return builder - } - - builder.Definition.Spec.Endpoints = endpoints - - return builder -} - -// WithLabels redefines the serviceMonitor with labels. -func (builder *Builder) WithLabels(labels map[string]string) *Builder { - if valid, _ := builder.validate(); !valid { - return builder - } - - glog.V(100).Infof("Defining serviceMonitor with labels: %v", labels) - - if len(labels) == 0 { - glog.V(100).Infof("labels can not be empty") - - builder.errorMsg = "labels can not be empty" - - return builder - } - - for key := range labels { - if key == "" { - glog.V(100).Infof("The 'labels' key cannot be empty") - - builder.errorMsg = "can not apply a labels with an empty key" - - return builder - } - } - - builder.Definition.Labels = labels - - return builder -} - -// WithSelector redefines the serviceMonitor with selector. -func (builder *Builder) WithSelector(selector map[string]string) *Builder { - if valid, _ := builder.validate(); !valid { - return builder - } - - glog.V(100).Infof("Defining serviceMonitor with selector: %v", selector) - - if len(selector) == 0 { - glog.V(100).Infof("selector can not be empty") - - builder.errorMsg = "selector can not be empty" - - return builder - } - - for key := range selector { - if key == "" { - glog.V(100).Infof("The 'selector' key cannot be empty") - - builder.errorMsg = "can not apply a selector with an empty key" - - return builder - } - } - - builder.Definition.Spec.Selector.MatchLabels = selector - - return builder -} - -// WithNamespaceSelector redefines the serviceMonitor with namespaceSelector. -func (builder *Builder) WithNamespaceSelector(namespaceSelector []string) *Builder { - if valid, _ := builder.validate(); !valid { - return builder - } - - glog.V(100).Infof("Defining serviceMonitor with namespaceSelector: %v", namespaceSelector) - - if len(namespaceSelector) == 0 { - glog.V(100).Infof("namespaceSelector can not be empty") - - builder.errorMsg = "namespaceSelector can not be empty" - - return builder - } - - builder.Definition.Spec.NamespaceSelector = monv1.NamespaceSelector{ - MatchNames: namespaceSelector, - } - - return builder -} - -// validate will check that the builder and builder definition are properly initialized before -// accessing any member fields. -func (builder *Builder) validate() (bool, error) { - resourceCRD := "ServiceMonitor" - - if builder == nil { - glog.V(100).Infof("The %s builder is uninitialized", resourceCRD) - - return false, fmt.Errorf("error: received nil %s builder", resourceCRD) - } - - if builder.Definition == nil { - glog.V(100).Infof("The %s is undefined", resourceCRD) - - return false, fmt.Errorf(msg.UndefinedCrdObjectErrString(resourceCRD)) - } - - if builder.apiClient == nil { - glog.V(100).Infof("The %s builder apiclient is nil", resourceCRD) - - return false, fmt.Errorf("%s builder cannot have nil apiClient", resourceCRD) - } - - if builder.errorMsg != "" { - glog.V(100).Infof("The %s builder has error message: %s", resourceCRD, builder.errorMsg) - - return false, fmt.Errorf(builder.errorMsg) - } - - return true, nil -} diff --git a/tests/system-tests/vcore/internal/vcorecommon/cgroup-operator.go b/tests/system-tests/vcore/internal/vcorecommon/cgroup-operator.go index 91d635978..257c06e28 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/cgroup-operator.go +++ b/tests/system-tests/vcore/internal/vcorecommon/cgroup-operator.go @@ -4,6 +4,7 @@ import ( "fmt" "time" + "github.com/openshift-kni/eco-goinfra/pkg/reportxml" "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/platform" "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/cgroup" @@ -16,11 +17,57 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/openshift-kni/eco-goinfra/pkg/reportxml" . "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreinittools" "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreparams" ) +// VerifyCGroupDefault container that contains tests for cgroup verification. +func VerifyCGroupDefault() { + Describe( + "cgroup verification", + Label(vcoreparams.LabelVCoreDeployment), func() { + BeforeAll(func() { + By("Check that the current cluster version is greater or equal to the 4.15") + + isGreaterOrEqual, err := platform.CompareOCPVersionWithCurrent(APIClient, + "4.15", + true, + true) + Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("failed to compare versions due to %v", err)) + + if isGreaterOrEqual { + currentOCPVersion, err := platform.GetOCPVersion(APIClient) + Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("failed to get OCP version due to %v", err)) + + Skip(fmt.Sprintf("current OCP version %s is not greater or equal to the 4.15", + currentOCPVersion)) + } + + By("Insure cgroupv2 configured for the cluster") + + err = cgroup.SetLinuxCGroupVersion(APIClient, configv1.CgroupModeV2) + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("failed to change cluster cgroup mode to the %v due to %v", + configv1.CgroupModeV2, err)) + }) + + It("Verifies cgroupv2 is a default for the cluster deployment", + Label("cgroupv2"), reportxml.ID("73370"), VerifyCGroupV2IsADefault) + + It("Verifies that the cluster can be moved to the cgroupv1 and back", + Label("cgroupv2"), reportxml.ID("73371"), VerifySwitchBetweenCGroupVersions) + + AfterAll(func() { + By("Restore cgroupv2 cluster configuration") + + err := cgroup.SetLinuxCGroupVersion(APIClient, configv1.CgroupModeV2) + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("failed to change cluster cgroup mode to the %v due to %v", + configv1.CgroupModeV2, err)) + }) + }) +} + // VerifyCGroupV2IsADefault assert cGroupV2 is a default for the cluster deployment. func VerifyCGroupV2IsADefault(ctx SpecContext) { glog.V(vcoreparams.VCoreLogLevel).Infof("Verify cgroupv2 is a default for the cluster deployment") @@ -69,50 +116,3 @@ func VerifySwitchBetweenCGroupVersions(ctx SpecContext) { Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("failed to change cluster cgroup mode to the %v due to %v", configv1.CgroupModeV2, err)) } // func VerifySwitchBetweenCGroupVersions (ctx SpecContext) - -// VerifyCGroupDefault container that contains tests for cgroup verification. -func VerifyCGroupDefault() { - Describe( - "cgroup verification", - Label(vcoreparams.LabelVCoreDeployment), func() { - BeforeAll(func() { - By("Check that the current cluster version is greater or equal to the 4.15") - - isGreaterOrEqual, err := platform.CompareOCPVersionWithCurrent(APIClient, - "4.15", - true, - true) - Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("failed to compare versions due to %v", err)) - - if isGreaterOrEqual { - currentOCPVersion, err := platform.GetOCPVersion(APIClient) - Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("failed to get OCP version due to %v", err)) - - Skip(fmt.Sprintf("current OCP version %s is not greater or equal to the 4.15", - currentOCPVersion)) - } - - By("Insure cgroupv2 configured for the cluster") - - err = cgroup.SetLinuxCGroupVersion(APIClient, configv1.CgroupModeV2) - Expect(err).ToNot(HaveOccurred(), - fmt.Sprintf("failed to change cluster cgroup mode to the %v due to %v", - configv1.CgroupModeV2, err)) - }) - - It("Verifies cgroupv2 is a default for the cluster deployment", - Label("cgroupv2"), reportxml.ID("73370"), VerifyCGroupV2IsADefault) - - It("Verifies that the cluster can be moved to the cgroupv1 and back", - Label("cgroupv2"), reportxml.ID("73371"), VerifySwitchBetweenCGroupVersions) - - AfterAll(func() { - By("Restore cgroupv2 cluster configuration") - - err := cgroup.SetLinuxCGroupVersion(APIClient, configv1.CgroupModeV2) - Expect(err).ToNot(HaveOccurred(), - fmt.Sprintf("failed to change cluster cgroup mode to the %v due to %v", - configv1.CgroupModeV2, err)) - }) - }) -} diff --git a/tests/system-tests/vcore/internal/vcorecommon/esk-clo-operator.go b/tests/system-tests/vcore/internal/vcorecommon/esk-clo-operator.go index 9e260e9b4..1b432d031 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/esk-clo-operator.go +++ b/tests/system-tests/vcore/internal/vcorecommon/esk-clo-operator.go @@ -6,6 +6,8 @@ import ( "path/filepath" "time" + "github.com/openshift-kni/eco-goinfra/pkg/reportxml" + "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/apiobjectshelper" "github.com/openshift-kni/eco-goinfra/pkg/console" @@ -17,7 +19,6 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" clusterlogging "github.com/openshift-kni/eco-goinfra/pkg/clusterlogging" - "github.com/openshift-kni/eco-goinfra/pkg/reportxml" . "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreinittools" "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreparams" ) @@ -32,6 +33,29 @@ var ( esoInstances = "3" ) +// VerifyESKAndCLOSuite container that contains tests for ElasticSearch and ClusterLogging verification. +func VerifyESKAndCLOSuite() { + Describe( + "ElasticSearch and Cluster Logging validation", + Label(vcoreparams.LabelVCoreOperators), func() { + It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.ESKNamespace), + Label("clo"), VerifyESKNamespaceExists) + + It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.CLONamespace), + Label("clo"), VerifyCLONamespaceExists) + + It("Verify ElasticSearch Operator successfully installed", + Label("clo"), reportxml.ID("59493"), VerifyESKDeployment) + + It(fmt.Sprintf("Verify Cluster Logging instance %s is running in namespace %s", + vcoreparams.CLOInstanceName, vcoreparams.CLONamespace), + Label("clo"), reportxml.ID("59494"), CreateCLOInstance) + + It("Verify ClusterLogging Operator successfully installed", + Label("clo"), reportxml.ID("73678"), VerifyCLODeployment) + }) +} + // VerifyESKNamespaceExists asserts namespace for ElasticSearch Operator exists. func VerifyESKNamespaceExists(ctx SpecContext) { err := apiobjectshelper.VerifyNamespaceExists(APIClient, vcoreparams.ESKNamespace, time.Second) @@ -197,26 +221,3 @@ func CreateCLOInstance(ctx SpecContext) { _, err = consoleoperatorObj.WithPlugins([]string{"logging-view-plugin"}, false).Update() Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("failed to enable logging-view-pluggin due to %v", err)) } // func CreateCLOInstance (ctx SpecContext) - -// VerifyESKAndCLOSuite container that contains tests for ElasticSearch and ClusterLogging verification. -func VerifyESKAndCLOSuite() { - Describe( - "ElasticSearch and Cluster Logging validation", - Label(vcoreparams.LabelVCoreOperators), func() { - It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.ESKNamespace), - Label("clo"), VerifyESKNamespaceExists) - - It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.CLONamespace), - Label("clo"), VerifyCLONamespaceExists) - - It("Verify ElasticSearch Operator successfully installed", - Label("clo"), reportxml.ID("59493"), VerifyESKDeployment) - - It(fmt.Sprintf("Verify Cluster Logging instance %s is running in namespace %s", - vcoreparams.CLOInstanceName, vcoreparams.CLONamespace), - Label("clo"), reportxml.ID("59494"), CreateCLOInstance) - - It("Verify ClusterLogging Operator successfully installed", - Label("clo"), reportxml.ID("73678"), VerifyCLODeployment) - }) -} diff --git a/tests/system-tests/vcore/internal/vcorecommon/helm.go b/tests/system-tests/vcore/internal/vcorecommon/helm.go index 0ed2b3f1d..f3ed05853 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/helm.go +++ b/tests/system-tests/vcore/internal/vcorecommon/helm.go @@ -6,15 +6,41 @@ import ( "path/filepath" "strings" + "github.com/openshift-kni/eco-goinfra/pkg/reportxml" + "github.com/golang/glog" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/openshift-kni/eco-goinfra/pkg/reportxml" "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/files" "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/shell" "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreparams" ) +// VerifyHelmSuite container that contains tests for the Helm verification. +func VerifyHelmSuite() { + Describe( + "Helm validation", + Label(vcoreparams.LabelVCoreOperators), func() { + BeforeAll(func() { + By(fmt.Sprintf("Asserting %s folder exists", vcoreparams.ConfigurationFolderName)) + + homeDir, err := os.UserHomeDir() + Expect(err).To(BeNil(), fmt.Sprint(err)) + + vcoreConfigsFolder := filepath.Join(homeDir, vcoreparams.ConfigurationFolderName) + + glog.V(vcoreparams.VCoreLogLevel).Infof("vcoreConfigsFolder: %s", vcoreConfigsFolder) + + if err := os.Mkdir(vcoreConfigsFolder, 0755); os.IsExist(err) { + glog.V(vcoreparams.VCoreLogLevel).Infof("%s folder already exists", vcoreConfigsFolder) + } + }) + + It("Verify Helm deployment procedure", + Label("helm"), reportxml.ID("60085"), VerifyHelmDeploymentProcedure) + }) +} + // VerifyHelmDeploymentProcedure asserts Helm deployment procedure. func VerifyHelmDeploymentProcedure(ctx SpecContext) { glog.V(vcoreparams.VCoreLogLevel).Infof("Verify Helm could be installed and works correctly") @@ -56,28 +82,3 @@ func VerifyHelmDeploymentProcedure(ctx SpecContext) { Expect(strings.Contains(string(result), "version.BuildInfo")).To(Equal(true), fmt.Sprintf("Helm was not installed properly; %v", string(result))) } // func VerifyHelmDeploymentProcedure (ctx SpecContext) - -// VerifyHelmSuite container that contains tests for the Helm verification. -func VerifyHelmSuite() { - Describe( - "Helm validation", - Label(vcoreparams.LabelVCoreOperators), func() { - BeforeAll(func() { - By(fmt.Sprintf("Asserting %s folder exists", vcoreparams.ConfigurationFolderName)) - - homeDir, err := os.UserHomeDir() - Expect(err).To(BeNil(), fmt.Sprint(err)) - - vcoreConfigsFolder := filepath.Join(homeDir, vcoreparams.ConfigurationFolderName) - - glog.V(vcoreparams.VCoreLogLevel).Infof("vcoreConfigsFolder: %s", vcoreConfigsFolder) - - if err := os.Mkdir(vcoreConfigsFolder, 0755); os.IsExist(err) { - glog.V(vcoreparams.VCoreLogLevel).Infof("%s folder already exists", vcoreConfigsFolder) - } - }) - - It("Verify Helm deployment procedure", - Label("helm"), reportxml.ID("60085"), VerifyHelmDeploymentProcedure) - }) -} diff --git a/tests/system-tests/vcore/internal/vcorecommon/initial-platform-deployment.go b/tests/system-tests/vcore/internal/vcorecommon/initial-platform-deployment.go index ffdf463dd..4c9f047c0 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/initial-platform-deployment.go +++ b/tests/system-tests/vcore/internal/vcorecommon/initial-platform-deployment.go @@ -7,6 +7,8 @@ import ( "regexp" "time" + "github.com/openshift-kni/eco-goinfra/pkg/reportxml" + "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/ocpcli" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -20,11 +22,44 @@ import ( "github.com/openshift-kni/eco-goinfra/pkg/mco" "github.com/openshift-kni/eco-goinfra/pkg/nodes" - "github.com/openshift-kni/eco-goinfra/pkg/reportxml" . "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreinittools" "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreparams" ) +// VerifyInitialDeploymentConfig container that contains tests for initial cluster deployment verification. +func VerifyInitialDeploymentConfig() { + Describe( + "Initial deployment config validation", + Label(vcoreparams.LabelVCoreDeployment), func() { + It("Verifies healthy cluster status", + Label("healthy-cluster"), reportxml.ID("59441"), VerifyHealthyClusterStatus) + + It("Asserts time sync was successfully applied for master nodes", + Label("chrony"), reportxml.ID("60028"), VerifyEtcChronyMasters) + + It("Asserts time sync was successfully applied for workers nodes", + Label("chrony"), reportxml.ID("60029"), VerifyEtcChronyWorkers) + + It("Verifies odf MCP was deployed", + Label("odf"), reportxml.ID("73673"), VerifyODFMCPAvailability) + + It("Verifies full set of ODF nodes was deployed", + Label("odf"), reportxml.ID("59442"), VerifyODFNodesAvailability) + + It("Verifies control-plane-worker MCP was deployed", + Label("cp-mcp"), reportxml.ID("60049"), VerifyControlPlaneWorkerMCPAvailability) + + It("Verifies control-plane-worker nodes availability", + Label("cp-nodes"), reportxml.ID("59505"), VerifyControlPlaneWorkerNodesAvailability) + + It("Verifies user-plane-worker MCP was deployed", + Label("pp-mcp"), reportxml.ID("60050"), VerifyUserPlaneWorkerMCPAvailability) + + It("Verifies user-plane-worker nodes availability", + Label("pp-nodes"), reportxml.ID("59506"), VerifyUserPlaneWorkerNodesAvailability) + }) +} + // VerifyHealthyClusterStatus asserts healthy cluster status. func VerifyHealthyClusterStatus(ctx SpecContext) { glog.V(vcoreparams.VCoreLogLevel).Infof("Verify healthy cluster status") @@ -187,37 +222,3 @@ func VerifyUserPlaneWorkerMCPAvailability(ctx SpecContext) { func VerifyUserPlaneWorkerNodesAvailability(ctx SpecContext) { verifyNodesAvailability(VCoreConfig.VCorePpMCPName, VCoreConfig.VCorePpLabelListOption) } // func VerifyUserPlaneWorkerNodesAvailability (ctx SpecContext) - -// VerifyInitialDeploymentConfig container that contains tests for initial cluster deployment verification. -func VerifyInitialDeploymentConfig() { - Describe( - "Initial deployment config validation", - Label(vcoreparams.LabelVCoreDeployment), func() { - It("Verifies healthy cluster status", - Label("healthy-cluster"), reportxml.ID("59441"), VerifyHealthyClusterStatus) - - It("Asserts time sync was successfully applied for master nodes", - Label("chrony"), reportxml.ID("60028"), VerifyEtcChronyMasters) - - It("Asserts time sync was successfully applied for workers nodes", - Label("chrony"), reportxml.ID("60029"), VerifyEtcChronyWorkers) - - It("Verifies odf MCP was deployed", - Label("odf"), reportxml.ID("73673"), VerifyODFMCPAvailability) - - It("Verifies full set of ODF nodes was deployed", - Label("odf"), reportxml.ID("59442"), VerifyODFNodesAvailability) - - It("Verifies control-plane-worker MCP was deployed", - Label("cp-mcp"), reportxml.ID("60049"), VerifyControlPlaneWorkerMCPAvailability) - - It("Verifies control-plane-worker nodes availability", - Label("cp-nodes"), reportxml.ID("59505"), VerifyControlPlaneWorkerNodesAvailability) - - It("Verifies user-plane-worker MCP was deployed", - Label("pp-mcp"), reportxml.ID("60050"), VerifyUserPlaneWorkerMCPAvailability) - - It("Verifies user-plane-worker nodes availability", - Label("pp-nodes"), reportxml.ID("59506"), VerifyUserPlaneWorkerNodesAvailability) - }) -} diff --git a/tests/system-tests/vcore/internal/vcorecommon/keda-validation.go b/tests/system-tests/vcore/internal/vcorecommon/keda-validation.go index d2a41c5d6..970bad672 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/keda-validation.go +++ b/tests/system-tests/vcore/internal/vcorecommon/keda-validation.go @@ -3,35 +3,38 @@ package vcorecommon import ( "context" "fmt" - "github.com/openshift-kni/eco-goinfra/pkg/reportxml" - "github.com/openshift-kni/eco-goinfra/pkg/secret" - "k8s.io/apimachinery/pkg/util/wait" "os" "path/filepath" "time" - kedav1alpha1 "github.com/kedacore/keda-olm-operator/apis/keda/v1alpha1" - kedav2v1alpha1 "github.com/kedacore/keda/v2/apis/keda/v1alpha1" "github.com/openshift-kni/eco-goinfra/pkg/configmap" "github.com/openshift-kni/eco-goinfra/pkg/deployment" - "github.com/openshift-kni/eco-goinfra/pkg/keda" - "github.com/openshift-kni/eco-goinfra/pkg/namespace" + "github.com/openshift-kni/eco-goinfra/pkg/monitoring" "github.com/openshift-kni/eco-goinfra/pkg/rbac" + "github.com/openshift-kni/eco-goinfra/pkg/secret" "github.com/openshift-kni/eco-goinfra/pkg/service" "github.com/openshift-kni/eco-goinfra/pkg/serviceaccount" - "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/mirroring" - "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/ocpcli" - "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/platform" - "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/monitoring" + "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/await" monv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" + "github.com/openshift-kni/eco-goinfra/pkg/reportxml" + "k8s.io/apimachinery/pkg/util/wait" + "github.com/golang/glog" + kedav1alpha1 "github.com/kedacore/keda-olm-operator/apis/keda/v1alpha1" + kedav2v1alpha1 "github.com/kedacore/keda/v2/apis/keda/v1alpha1" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/openshift-kni/eco-goinfra/pkg/keda" + "github.com/openshift-kni/eco-goinfra/pkg/namespace" "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/apiobjectshelper" + "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/mirroring" + "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/ocpcli" + "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/platform" . "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreinittools" "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreparams" @@ -41,7 +44,6 @@ const ( kedaScaledObjectName = "prometheus-scaledobject" configmapName = "cluster-monitoring-config" configmapNamespace = "openshift-monitoring" - maxReplicaCount = 8 testAppServiceMonitorName = "keda-testing-sm" serviceAccountName = "thanos" saTokenName = "thanos-secret" @@ -88,6 +90,14 @@ func VerifyKedaSuite() { It("Verifies ScaleObject instance created successfully", Label("keda"), reportxml.ID("65007"), VerifyScaleObjectDeployment) + + AfterAll(func() { + By("Teardown") + + Expect(insureNamespaceNotExists(vcoreparams.KedaWatchNamespace)). + To(Equal(true), fmt.Sprintf("Failed to delete watch namespace %s", + vcoreparams.KedaWatchNamespace)) + }) }) } @@ -140,7 +150,7 @@ func VerifyKedaControllerDeployment(ctx SpecContext) { WithWatchNamespace(vcoreparams.KedaWatchNamespace). Create() Expect(err).ToNot(HaveOccurred(), - fmt.Sprintf("Failed to create kedaController instance %q in namespace %q due to: %w", + fmt.Sprintf("Failed to create kedaController instance %q in namespace %q due to: %v", vcoreparams.KedaControllerName, vcoreparams.KedaNamespace, err)) Expect(kedaControllerBuilder.Exists()).To(Equal(true), fmt.Sprintf( "no kedaController instance %s was found in the namespace %s", @@ -170,31 +180,9 @@ func VerifyScaleObjectDeployment(ctx SpecContext) { glog.V(vcoreparams.VCoreLogLevel).Info("Deploy application that exposes Prometheus metrics") - watchNamespace := namespace.NewBuilder(APIClient, vcoreparams.KedaWatchNamespace) - if watchNamespace.Exists() { - err = watchNamespace.Delete() - Expect(err).ToNot(HaveOccurred(), - fmt.Sprintf("Failed to delete watch namespace %s due to: %v", - vcoreparams.KedaWatchNamespace, err)) - - err := wait.PollUntilContextTimeout( - context.TODO(), - time.Second, - time.Second*30, - true, - func(ctx context.Context) (bool, error) { - isExists := watchNamespace.Exists() - - if !isExists { - return true, nil - } - - return false, nil - }) - Expect(err).ToNot(HaveOccurred(), - fmt.Sprintf("Failed to delete watch namespace %s due to: %v", - vcoreparams.KedaWatchNamespace, err)) - } + Expect(insureNamespaceNotExists(vcoreparams.KedaWatchNamespace)). + To(Equal(true), fmt.Sprintf("Failed to delete watch namespace %s", + vcoreparams.KedaWatchNamespace)) Expect(insureNamespaceExists(vcoreparams.KedaWatchNamespace)).To(Equal(true), fmt.Sprintf("failed to create namespace %s", vcoreparams.KedaWatchNamespace)) @@ -230,9 +218,9 @@ func VerifyScaleObjectDeployment(ctx SpecContext) { _, err = deployment.NewBuilder(APIClient, vcoreparams.KedaWatchAppName, vcoreparams.KedaWatchNamespace, - map[string]string{"app": vcoreparams.KedaWatchAppName, "type": "keda-testing"}, + map[string]string{"app": vcoreparams.KedaWatchAppName}, &appConteiner, - ).WithReplicas(int32(1)).Create() + ).WithLabel("type", "keda-testing").WithReplicas(int32(1)).Create() Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("Failed to create test application %s in namespace %s due to: %v", vcoreparams.KedaWatchAppName, vcoreparams.KedaWatchNamespace, err)) @@ -243,7 +231,7 @@ func VerifyScaleObjectDeployment(ctx SpecContext) { _, err = service.NewBuilder(APIClient, vcoreparams.KedaWatchAppName, vcoreparams.KedaWatchNamespace, - map[string]string{"app": vcoreparams.KedaWatchAppName}, + map[string]string{"type": "keda-testing"}, corev1.ServicePort{ Name: "http", Protocol: "TCP", @@ -253,7 +241,8 @@ func VerifyScaleObjectDeployment(ctx SpecContext) { IntVal: int32(8080), }, }, - ).WithAnnotation(map[string]string{"prometheus.io/scrape": "true"}).Create() + ).WithAnnotation(map[string]string{"prometheus.io/scrape": "true"}). + WithLabels(map[string]string{"app": vcoreparams.KedaWatchAppName}).Create() Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("Failed to create service %s in namespace %s due to: %v", vcoreparams.KedaWatchAppName, vcoreparams.KedaWatchNamespace, err)) @@ -269,7 +258,7 @@ func VerifyScaleObjectDeployment(ctx SpecContext) { _, err = monitoring.NewBuilder(APIClient, testAppServiceMonitorName, vcoreparams.KedaWatchNamespace).WithEndpoints(endpoints). - WithSelector(map[string]string{"app": "vcoreparams.KedaWatchAppName"}).Create() + WithSelector(map[string]string{"app": vcoreparams.KedaWatchAppName}).Create() Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("Failed to create serviceMonitor %s in namespace %s due to: %v", testAppServiceMonitorName, vcoreparams.KedaWatchNamespace, err)) @@ -335,6 +324,33 @@ func VerifyScaleObjectDeployment(ctx SpecContext) { fmt.Sprintf("Failed to create a role %s for reading metric from Thanos in namespace %s due to: %v", metricsReaderName, vcoreparams.KedaWatchNamespace, err)) + glog.V(vcoreparams.VCoreLogLevel).Infof("Create a roleBinding %s for serviceaccount %s in namespace %s", + metricsReaderName, serviceAccountName, vcoreparams.KedaWatchNamespace) + + kedaRoleBindingTemplateName := "keda-rolebinding.yaml" + varsToReplace := make(map[string]interface{}) + varsToReplace["RoleBindingName"] = metricsReaderName + varsToReplace["RoleBindingNamespace"] = vcoreparams.KedaWatchNamespace + varsToReplace["ServiceAccountName"] = serviceAccountName + varsToReplace["RoleName"] = metricsReaderName + homeDir, err := os.UserHomeDir() + Expect(err).ToNot(HaveOccurred(), "user home directory not found; %s", err) + + destinationDirectoryPath := filepath.Join(homeDir, vcoreparams.ConfigurationFolderName) + + workingDir, err := os.Getwd() + Expect(err).ToNot(HaveOccurred(), err) + + templateDir := filepath.Join(workingDir, vcoreparams.TemplateFilesFolder) + + err = ocpcli.CreateConfig( + templateDir, + kedaRoleBindingTemplateName, + destinationDirectoryPath, + kedaRoleBindingTemplateName, + varsToReplace) + Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("failed to create load job due to %v", err)) + glog.V(vcoreparams.VCoreLogLevel).Infof("Define scaledObject instance %s in namespace %s", kedaScaledObjectName, vcoreparams.KedaWatchNamespace) @@ -378,19 +394,9 @@ func VerifyScaleObjectDeployment(ctx SpecContext) { prometheusOriginMirrorURL, prometheusImageName, prometheusImageTag, err)) appLoadJobTemplateName := "keda-test-app-load-job.yaml" - varsToReplace := make(map[string]interface{}) varsToReplace["KedaWatchNamespace"] = vcoreparams.KedaWatchNamespace varsToReplace["TestNamespace"] = vcoreparams.KedaWatchNamespace varsToReplace["AbImageURL"] = abImageURL - homeDir, err := os.UserHomeDir() - Expect(err).ToNot(HaveOccurred(), "user home directory not found; %s", err) - - destinationDirectoryPath := filepath.Join(homeDir, vcoreparams.ConfigurationFolderName) - - workingDir, err := os.Getwd() - Expect(err).ToNot(HaveOccurred(), err) - - templateDir := filepath.Join(workingDir, vcoreparams.TemplateFilesFolder) err = ocpcli.CreateConfig( templateDir, @@ -399,6 +405,17 @@ func VerifyScaleObjectDeployment(ctx SpecContext) { appLoadJobTemplateName, varsToReplace) Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("failed to create load job due to %v", err)) + + glog.V(vcoreparams.VCoreLogLevel).Info("Wait until pods replicas count reach 8") + + isCntReached, err := await.WaitForThePodReplicasCountInNamespace(APIClient, + vcoreparams.KedaWatchNamespace, metav1.ListOptions{ + LabelSelector: "app=test-app", + }, 8, time.Minute*5) + Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("failed to scale %s pods in namespace %s due to %v", + vcoreparams.KedaWatchAppName, vcoreparams.KedaWatchNamespace, err)) + Expect(isCntReached).To(Equal(true), fmt.Sprintf("failed to scale %s pods in namespace %s after %v", + vcoreparams.KedaWatchAppName, vcoreparams.KedaWatchNamespace, time.Minute*5)) } // func VerifyKedaControllerDeployment (ctx SpecContext) func getImageURL(repository, name, tag string) (string, error) { @@ -433,7 +450,37 @@ func getImageURL(repository, name, tag string) (string, error) { } } - return imageURL, nil + return fmt.Sprintf("%s:%s", imageURL, tag), nil +} + +func insureNamespaceNotExists(nsName string) bool { + watchNamespace := namespace.NewBuilder(APIClient, nsName) + if watchNamespace.Exists() { + err := watchNamespace.Delete() + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("Failed to delete watch namespace %s due to: %v", + vcoreparams.KedaWatchNamespace, err)) + + err = wait.PollUntilContextTimeout( + context.TODO(), + time.Second, + time.Minute*10, + true, + func(ctx context.Context) (bool, error) { + isExists := watchNamespace.Exists() + + if !isExists { + return true, nil + } + + return false, nil + }) + Expect(err).ToNot(HaveOccurred(), + fmt.Sprintf("Failed to delete watch namespace %s due to: %v", + vcoreparams.KedaWatchNamespace, err)) + } + + return true } func insureNamespaceExists(nsName string) bool { @@ -442,7 +489,6 @@ func insureNamespaceExists(nsName string) bool { createNs := namespace.NewBuilder(APIClient, nsName) if !createNs.Exists() { - createNs, err := createNs.Create() if err != nil { diff --git a/tests/system-tests/vcore/internal/vcorecommon/local-storage-operator.go b/tests/system-tests/vcore/internal/vcorecommon/local-storage-operator.go index b52b10b75..b401d492a 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/local-storage-operator.go +++ b/tests/system-tests/vcore/internal/vcorecommon/local-storage-operator.go @@ -21,6 +21,19 @@ var ( lvsName = "ocs-deviceset" ) +// VerifyLSOSuite container that contains tests for LSO verification. +func VerifyLSOSuite() { + Describe( + "LSO validation", + Label(vcoreparams.LabelVCoreOperators), func() { + It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.LSONamespace), + Label("lso"), VerifyLSONamespaceExists) + + It("Verify Local Storage Operator successfully installed", + Label("lso"), reportxml.ID("59491"), VerifyLSODeployment) + }) +} + // VerifyLSONamespaceExists asserts namespace for Local Storage Operator exists. func VerifyLSONamespaceExists(ctx SpecContext) { err := apiobjectshelper.VerifyNamespaceExists(APIClient, vcoreparams.LSONamespace, time.Second) @@ -69,16 +82,3 @@ func VerifyLSODeployment(ctx SpecContext) { Expect(lvsInstance.Exists()).To(Equal(true), fmt.Sprintf("%s localvolumeset not found in %s namespace", lvsName, vcoreparams.LSONamespace)) } // func VerifyLSODeployment (ctx SpecContext) - -// VerifyLSOSuite container that contains tests for LSO verification. -func VerifyLSOSuite() { - Describe( - "LSO validation", - Label(vcoreparams.LabelVCoreOperators), func() { - It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.LSONamespace), - Label("lso"), VerifyLSONamespaceExists) - - It("Verify Local Storage Operator successfully installed", - Label("lso"), reportxml.ID("59491"), VerifyLSODeployment) - }) -} diff --git a/tests/system-tests/vcore/internal/vcorecommon/metallb-operator.go b/tests/system-tests/vcore/internal/vcorecommon/metallb-operator.go index d58103178..e4b92af02 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/metallb-operator.go +++ b/tests/system-tests/vcore/internal/vcorecommon/metallb-operator.go @@ -6,12 +6,12 @@ import ( "path/filepath" "time" + "github.com/openshift-kni/eco-goinfra/pkg/reportxml" + "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/apiobjectshelper" "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/await" "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/csv" - "github.com/openshift-kni/eco-goinfra/pkg/reportxml" - "github.com/golang/glog" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -22,6 +22,31 @@ import ( "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreparams" ) +// VerifyMetaLBSuite container that contains tests for MetalLB verification. +func VerifyMetaLBSuite() { + Describe( + "MetalLB validation", + Label(vcoreparams.LabelVCoreOperators), func() { + BeforeAll(func() { + By(fmt.Sprintf("Asserting %s folder exists", vcoreparams.ConfigurationFolderName)) + + homeDir, err := os.UserHomeDir() + Expect(err).To(BeNil(), fmt.Sprint(err)) + + vcoreConfigsFolder := filepath.Join(homeDir, vcoreparams.ConfigurationFolderName) + + if err := os.Mkdir(vcoreConfigsFolder, 0755); os.IsExist(err) { + glog.V(vcoreparams.VCoreLogLevel).Infof("%s folder already exists", vcoreConfigsFolder) + } + }) + It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.MetalLBOperatorNamespace), + Label("metallb"), VerifyMetalLBNamespaceExists) + + It("Verify MetalLB operator successfully installed", + Label("metallb"), reportxml.ID("60036"), VerifyMetalLBOperatorDeployment) + }) +} + // VerifyMetalLBNamespaceExists asserts namespace for NMState operator exists. func VerifyMetalLBNamespaceExists(ctx SpecContext) { err := apiobjectshelper.VerifyNamespaceExists(APIClient, vcoreparams.MetalLBOperatorNamespace, time.Second) @@ -113,28 +138,3 @@ func VerifyMetalLBOperatorDeployment(ctx SpecContext) { Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("daemonset for %s deployment speaker not found in %s namespace; %v", vcoreparams.MetalLBOperatorDeploymentName, vcoreparams.MetalLBOperatorNamespace, err)) } // func VerifyMetalLBOperatorDeployment (ctx SpecContext) - -// VerifyMetaLBSuite container that contains tests for MetalLB verification. -func VerifyMetaLBSuite() { - Describe( - "MetalLB validation", - Label(vcoreparams.LabelVCoreOperators), func() { - BeforeAll(func() { - By(fmt.Sprintf("Asserting %s folder exists", vcoreparams.ConfigurationFolderName)) - - homeDir, err := os.UserHomeDir() - Expect(err).To(BeNil(), fmt.Sprint(err)) - - vcoreConfigsFolder := filepath.Join(homeDir, vcoreparams.ConfigurationFolderName) - - if err := os.Mkdir(vcoreConfigsFolder, 0755); os.IsExist(err) { - glog.V(vcoreparams.VCoreLogLevel).Infof("%s folder already exists", vcoreConfigsFolder) - } - }) - It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.MetalLBOperatorNamespace), - Label("metallb"), VerifyMetalLBNamespaceExists) - - It("Verify MetalLB operator successfully installed", - Label("metallb"), reportxml.ID("60036"), VerifyMetalLBOperatorDeployment) - }) -} diff --git a/tests/system-tests/vcore/internal/vcorecommon/nmstate-validation.go b/tests/system-tests/vcore/internal/vcorecommon/nmstate-validation.go index 2b6705fa3..0bcd83853 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/nmstate-validation.go +++ b/tests/system-tests/vcore/internal/vcorecommon/nmstate-validation.go @@ -5,6 +5,8 @@ import ( "fmt" "time" + "github.com/openshift-kni/eco-goinfra/pkg/reportxml" + "github.com/golang/glog" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -13,13 +15,31 @@ import ( goclient "sigs.k8s.io/controller-runtime/pkg/client" "github.com/openshift-kni/eco-goinfra/pkg/nmstate" - "github.com/openshift-kni/eco-goinfra/pkg/reportxml" "k8s.io/apimachinery/pkg/util/wait" . "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreinittools" "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreparams" ) +// VerifyNMStateSuite container that contains tests for NMState verification. +func VerifyNMStateSuite() { + Describe( + "NMState validation", + Label(vcoreparams.LabelVCoreOperators), func() { + It(fmt.Sprintf("Verifies %s namespace exists", VCoreConfig.NMStateOperatorNamespace), + Label("nmstate"), VerifyNMStateNamespaceExists) + + It("Verifies NMState operator deployment succeeded", + Label("nmstate"), reportxml.ID("67027"), VerifyNMStateCSVConditionSucceeded) + + It("Verifies NMState instance exists", + Label("nmstate"), reportxml.ID("67027"), VerifyNMStateInstanceExists) + + It("Verifies all NodeNetworkConfigurationPolicies are Available", + Label("nmstate"), reportxml.ID("71846"), VerifyAllNNCPsAreOK) + }) +} + // VerifyNMStateNamespaceExists asserts namespace for NMState operator exists. func VerifyNMStateNamespaceExists(ctx SpecContext) { err := apiobjectshelper.VerifyNamespaceExists(APIClient, VCoreConfig.NMStateOperatorNamespace, time.Second) @@ -115,22 +135,3 @@ func VerifyAllNNCPsAreOK(ctx SpecContext) { Expect(len(degradedNNCP)).To(Equal(0), "There are Degraded NodeNetworkConfigurationPolicies") Expect(len(nonAvailableNNCP)).To(Equal(0), "There are Progressing NodeNetworkConfigurationPolicies") } // func VerifyNNCP (ctx SpecContext) - -// VerifyNMStateSuite container that contains tests for NMState verification. -func VerifyNMStateSuite() { - Describe( - "NMState validation", - Label(vcoreparams.LabelVCoreOperators), func() { - It(fmt.Sprintf("Verifies %s namespace exists", VCoreConfig.NMStateOperatorNamespace), - Label("nmstate"), VerifyNMStateNamespaceExists) - - It("Verifies NMState operator deployment succeeded", - Label("nmstate"), reportxml.ID("67027"), VerifyNMStateCSVConditionSucceeded) - - It("Verifies NMState instance exists", - Label("nmstate"), reportxml.ID("67027"), VerifyNMStateInstanceExists) - - It("Verifies all NodeNetworkConfigurationPolicies are Available", - Label("nmstate"), reportxml.ID("71846"), VerifyAllNNCPsAreOK) - }) -} diff --git a/tests/system-tests/vcore/internal/vcorecommon/node-tuning-operator.go b/tests/system-tests/vcore/internal/vcorecommon/node-tuning-operator.go index e784cab0f..0eaeb36eb 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/node-tuning-operator.go +++ b/tests/system-tests/vcore/internal/vcorecommon/node-tuning-operator.go @@ -5,6 +5,8 @@ import ( "strings" "time" + "github.com/openshift-kni/eco-goinfra/pkg/reportxml" + "k8s.io/apimachinery/pkg/api/resource" "github.com/openshift-kni/eco-goinfra/pkg/clusteroperator" @@ -21,8 +23,6 @@ import ( kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1" "github.com/openshift-kni/eco-goinfra/pkg/pod" - "github.com/openshift-kni/eco-goinfra/pkg/reportxml" - v2 "github.com/openshift/cluster-node-tuning-operator/pkg/apis/performanceprofile/v2" "github.com/golang/glog" @@ -31,6 +31,35 @@ import ( . "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreinittools" ) +// VerifyNTOSuite container that contains tests for Node Tuning Operator verification. +func VerifyNTOSuite() { + Describe( + "NTO validation", //nolint:misspell + Label(vcoreparams.LabelVCoreOperators), func() { + It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.NTONamespace), + Label("nto"), VerifyNTONamespaceExists) //nolint:misspell + + It("Verify Node Tuning Operator successfully installed", + Label("nto"), reportxml.ID("63656"), VerifyNTODeployment) //nolint:misspell + + It("Create new performanceprofile", + Label("nto"), reportxml.ID("63741"), CreatePerformanceProfile) //nolint:misspell + + It("Create new nodes tuning", + Label("nto"), reportxml.ID("63740"), CreateNodesTuning) //nolint:misspell + + It("Verify CPU Manager config", + Label("nto"), reportxml.ID("63809"), VerifyCPUManagerConfig) //nolint:misspell + + It("Verify Node Tuning Operator Huge Pages configuration", + Label("nto"), reportxml.ID("60062"), VerifyHugePagesConfig) //nolint:misspell + + It("Verify System Reserved memory for user-plane-worker nodes configuration", + Label("nto"), //nolint:misspell + reportxml.ID("60047"), SetSystemReservedMemoryForUserPlaneNodes) + }) +} + // VerifyNTONamespaceExists asserts namespace for Node Tuning Operator exists. func VerifyNTONamespaceExists(ctx SpecContext) { err := apiobjectshelper.VerifyNamespaceExists(APIClient, vcoreparams.NTONamespace, time.Second) @@ -130,7 +159,7 @@ func CreatePerformanceProfile(ctx SpecContext) { WithGloballyDisableIrqLoadBalancing(). WithHugePages(vcoreparams.HugePagesSize, hugePages). WithNumaTopology(vcoreparams.TopologyConfig). - WithWorkloadHints(false, false, false) + WithWorkloadHints(false, true, false) if !ppObj.Exists() { glog.V(vcoreparams.VCoreLogLevel).Infof("Create new performanceprofile %s", VCoreConfig.VCorePpMCPName) @@ -370,35 +399,6 @@ func SetSystemReservedMemoryForUserPlaneNodes(ctx SpecContext) { } } // func SetSystemReservedMemoryForUserPlaneNodes (ctx SpecContext) -// VerifyNTOSuite container that contains tests for Node Tuning Operator verification. -func VerifyNTOSuite() { - Describe( - "NTO validation", //nolint:misspell - Label(vcoreparams.LabelVCoreOperators), func() { - It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.NTONamespace), - Label("nto"), VerifyNTONamespaceExists) //nolint:misspell - - It("Verify Node Tuning Operator successfully installed", - Label("nto"), reportxml.ID("63656"), VerifyNTODeployment) //nolint:misspell - - It("Create new performanceprofile", - Label("nto"), reportxml.ID("63741"), CreatePerformanceProfile) //nolint:misspell - - It("Create new nodes tuning", - Label("nto"), reportxml.ID("63740"), CreateNodesTuning) //nolint:misspell - - It("Verify CPU Manager config", - Label("nto"), reportxml.ID("63809"), VerifyCPUManagerConfig) //nolint:misspell - - It("Verify Node Tuning Operator Huge Pages configuration", - Label("nto"), reportxml.ID("60062"), VerifyHugePagesConfig) //nolint:misspell - - It("Verify System Reserved memory for user-plane-worker nodes configuration", - Label("nto"), //nolint:misspell - reportxml.ID("60047"), SetSystemReservedMemoryForUserPlaneNodes) - }) -} - // unmarshalRaw converts raw bytes for a K8s CR into the actual type. func unmarshalRaw[T any](raw []byte) T { untyped := &unstructured.Unstructured{} diff --git a/tests/system-tests/vcore/internal/vcorecommon/odf.go b/tests/system-tests/vcore/internal/vcorecommon/odf.go index 048458186..486961870 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/odf.go +++ b/tests/system-tests/vcore/internal/vcorecommon/odf.go @@ -4,10 +4,11 @@ import ( "fmt" "time" + "github.com/openshift-kni/eco-goinfra/pkg/reportxml" + "github.com/openshift-kni/eco-goinfra/pkg/console" "github.com/openshift-kni/eco-goinfra/pkg/deployment" "github.com/openshift-kni/eco-goinfra/pkg/pod" - "github.com/openshift-kni/eco-goinfra/pkg/reportxml" "github.com/openshift-kni/eco-goinfra/pkg/storage" ocsoperatorv1 "github.com/red-hat-storage/ocs-operator/api/v1" corev1 "k8s.io/api/core/v1" @@ -34,6 +35,22 @@ var ( volumeMode = corev1.PersistentVolumeBlock ) +// VerifyODFSuite container that contains tests for ODF verification. +func VerifyODFSuite() { + Describe( + "ODF validation", + Label(vcoreparams.LabelVCoreOperators), func() { + It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.ODFNamespace), + Label("odf"), VerifyODFNamespaceExists) + + It("Verify ODF successfully installed", + Label("odf"), reportxml.ID("63844"), VerifyODFDeployment) + + It("Verify ODF operator configuration procedure", + Label("odf"), reportxml.ID("59487"), VerifyODFConfig) + }) +} + // VerifyODFNamespaceExists asserts namespace for ODF exists. func VerifyODFNamespaceExists(ctx SpecContext) { err := apiobjectshelper.VerifyNamespaceExists(APIClient, vcoreparams.ODFNamespace, time.Second) @@ -146,19 +163,3 @@ func VerifyODFConfig(ctx SpecContext) { fmt.Sprintf("Failed to createstorageCluster %s instance in %s namespace; "+ "%v", storageclusterName, vcoreparams.ODFNamespace, err)) } // func VerifyODFConfig (ctx SpecContext) - -// VerifyODFSuite container that contains tests for ODF verification. -func VerifyODFSuite() { - Describe( - "ODF validation", - Label(vcoreparams.LabelVCoreOperators), func() { - It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.ODFNamespace), - Label("odf"), VerifyODFNamespaceExists) - - It("Verify ODF successfully installed", - Label("odf"), reportxml.ID("63844"), VerifyODFDeployment) - - It("Verify ODF operator configuration procedure", - Label("odf"), reportxml.ID("59487"), VerifyODFConfig) - }) -} diff --git a/tests/system-tests/vcore/internal/vcorecommon/post-deployment-config.go b/tests/system-tests/vcore/internal/vcorecommon/post-deployment-config.go index 3c96884b4..4f44f304e 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/post-deployment-config.go +++ b/tests/system-tests/vcore/internal/vcorecommon/post-deployment-config.go @@ -6,6 +6,8 @@ import ( "path/filepath" "time" + "github.com/openshift-kni/eco-goinfra/pkg/reportxml" + "github.com/openshift-kni/eco-goinfra/pkg/clusterversion" "github.com/openshift-kni/eco-goinfra/pkg/clusteroperator" @@ -22,11 +24,47 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/openshift-kni/eco-goinfra/pkg/reportxml" . "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreinittools" "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreparams" ) +// VerifyPostDeploymentConfig container that contains tests for basic post-deployment config verification. +func VerifyPostDeploymentConfig() { + Describe( + "Post-deployment config validation", + Label(vcoreparams.LabelVCoreDeployment), func() { + BeforeAll(func() { + By(fmt.Sprintf("Asserting %s folder exists", vcoreparams.ConfigurationFolderName)) + + homeDir, err := os.UserHomeDir() + Expect(err).To(BeNil(), fmt.Sprint(err)) + + vcoreConfigsFolder := filepath.Join(homeDir, vcoreparams.ConfigurationFolderName) + + glog.V(vcoreparams.VCoreLogLevel).Infof("vcoreConfigsFolder: %s", vcoreConfigsFolder) + + if err := os.Mkdir(vcoreConfigsFolder, 0755); os.IsExist(err) { + glog.V(vcoreparams.VCoreLogLevel).Infof("%s folder already exists", vcoreConfigsFolder) + } + }) + + It("Verifies Image Registry management state is Enabled", + Label("image-registry"), reportxml.ID("72812"), VerifyImageRegistryManagementStateEnablement) + + It("Verifies network policy configuration procedure", + Label("network-policy"), reportxml.ID("60086"), VerifyNetworkPolicyConfig) + + It("Verify scc activation succeeded", + Label("scc"), reportxml.ID("60042"), VerifySCCActivation) + + It("Verifies sctp module activation succeeded", + Label("sctp"), reportxml.ID("60086"), VerifySCTPModuleActivation) + + It("Verifies system reserved memory for masters succeeded", + Label("system-reserved"), reportxml.ID("60045"), SetSystemReservedMemoryForMasterNodes) + }) +} + // VerifyImageRegistryManagementStateEnablement asserts imageRegistry managementState can be changed to the Managed. func VerifyImageRegistryManagementStateEnablement(ctx SpecContext) { glog.V(vcoreparams.VCoreLogLevel).Infof("Enable local imageregistryconfig; change ManagementState to the Managed") @@ -259,40 +297,3 @@ func SetSystemReservedMemoryForMasterNodes(ctx SpecContext) { } } } // func SetSystemReservedMemoryForMasterNodes (ctx SpecContext) - -// VerifyPostDeploymentConfig container that contains tests for basic post-deployment config verification. -func VerifyPostDeploymentConfig() { - Describe( - "Post-deployment config validation", - Label(vcoreparams.LabelVCoreDeployment), func() { - BeforeAll(func() { - By(fmt.Sprintf("Asserting %s folder exists", vcoreparams.ConfigurationFolderName)) - - homeDir, err := os.UserHomeDir() - Expect(err).To(BeNil(), fmt.Sprint(err)) - - vcoreConfigsFolder := filepath.Join(homeDir, vcoreparams.ConfigurationFolderName) - - glog.V(vcoreparams.VCoreLogLevel).Infof("vcoreConfigsFolder: %s", vcoreConfigsFolder) - - if err := os.Mkdir(vcoreConfigsFolder, 0755); os.IsExist(err) { - glog.V(vcoreparams.VCoreLogLevel).Infof("%s folder already exists", vcoreConfigsFolder) - } - }) - - It("Verifies Image Registry management state is Enabled", - Label("image-registry"), reportxml.ID("72812"), VerifyImageRegistryManagementStateEnablement) - - It("Verifies network policy configuration procedure", - Label("network-policy"), reportxml.ID("60086"), VerifyNetworkPolicyConfig) - - It("Verify scc activation succeeded", - Label("scc"), reportxml.ID("60042"), VerifySCCActivation) - - It("Verifies sctp module activation succeeded", - Label("sctp"), reportxml.ID("60086"), VerifySCTPModuleActivation) - - It("Verifies system reserved memory for masters succeeded", - Label("system-reserved"), reportxml.ID("60045"), SetSystemReservedMemoryForMasterNodes) - }) -} diff --git a/tests/system-tests/vcore/internal/vcorecommon/redis.go b/tests/system-tests/vcore/internal/vcorecommon/redis.go index 7f4b2463b..37e581739 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/redis.go +++ b/tests/system-tests/vcore/internal/vcorecommon/redis.go @@ -7,6 +7,8 @@ import ( "strings" "time" + "github.com/openshift-kni/eco-goinfra/pkg/reportxml" + "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/platform" "github.com/openshift-kni/eco-goinfra/pkg/statefulset" @@ -23,12 +25,34 @@ import ( "github.com/golang/glog" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/openshift-kni/eco-goinfra/pkg/reportxml" "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/shell" . "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreinittools" "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreparams" ) +// VerifyRedisSuite container that contains tests for the Redis deployment verification. +func VerifyRedisSuite() { + Describe( + "Redis validation", + Label(vcoreparams.LabelVCoreOperators), func() { + BeforeAll(func() { + By(fmt.Sprintf("Asserting %s folder exists", vcoreparams.ConfigurationFolderName)) + + homeDir, err := os.UserHomeDir() + Expect(err).To(BeNil(), fmt.Sprint(err)) + + vcoreConfigsFolder := filepath.Join(homeDir, vcoreparams.ConfigurationFolderName) + + if err := os.Mkdir(vcoreConfigsFolder, 0755); os.IsExist(err) { + glog.V(vcoreparams.VCoreLogLevel).Infof("%s folder already exists", vcoreConfigsFolder) + } + }) + + It("Verify Redis deployment procedure", + Label("redis"), reportxml.ID("59503"), VerifyRedisDeploymentProcedure) + }) +} + // VerifyRedisDeploymentProcedure asserts Redis deployment procedure. // //nolint:funlen @@ -201,26 +225,3 @@ func VerifyRedisDeploymentProcedure(ctx SpecContext) { "expected: 3, found: %d", redisAppName, redisNamespace, len(podsList))) } } // func VerifyRedisDeploymentProcedure (ctx SpecContext) - -// VerifyRedisSuite container that contains tests for the Redis deployment verification. -func VerifyRedisSuite() { - Describe( - "Redis validation", - Label(vcoreparams.LabelVCoreOperators), func() { - BeforeAll(func() { - By(fmt.Sprintf("Asserting %s folder exists", vcoreparams.ConfigurationFolderName)) - - homeDir, err := os.UserHomeDir() - Expect(err).To(BeNil(), fmt.Sprint(err)) - - vcoreConfigsFolder := filepath.Join(homeDir, vcoreparams.ConfigurationFolderName) - - if err := os.Mkdir(vcoreConfigsFolder, 0755); os.IsExist(err) { - glog.V(vcoreparams.VCoreLogLevel).Infof("%s folder already exists", vcoreConfigsFolder) - } - }) - - It("Verify Redis deployment procedure", - Label("redis"), reportxml.ID("59503"), VerifyRedisDeploymentProcedure) - }) -} diff --git a/tests/system-tests/vcore/internal/vcorecommon/smo-validation.go b/tests/system-tests/vcore/internal/vcorecommon/smo-validation.go index b128ab3ba..981f942a6 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/smo-validation.go +++ b/tests/system-tests/vcore/internal/vcorecommon/smo-validation.go @@ -6,6 +6,8 @@ import ( "path/filepath" "time" + "github.com/openshift-kni/eco-goinfra/pkg/reportxml" + "github.com/openshift-kni/eco-gotests/tests/system-tests/internal/apiobjectshelper" "github.com/openshift-kni/eco-goinfra/pkg/pod" @@ -19,11 +21,56 @@ import ( . "github.com/onsi/gomega" "github.com/openshift-kni/eco-goinfra/pkg/namespace" - "github.com/openshift-kni/eco-goinfra/pkg/reportxml" . "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreinittools" "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreparams" ) +// VerifyServiceMeshSuite container that contains tests for Service Mesh verification. +func VerifyServiceMeshSuite() { + Describe( + "Service Mesh Operator deployment and configuration validation", + Label(vcoreparams.LabelVCoreOperators), func() { + BeforeAll(func() { + By(fmt.Sprintf("Asserting %s folder exists", vcoreparams.ConfigurationFolderName)) + + homeDir, err := os.UserHomeDir() + Expect(err).To(BeNil(), fmt.Sprint(err)) + + vcoreConfigsFolder := filepath.Join(homeDir, vcoreparams.ConfigurationFolderName) + + glog.V(100).Infof("vcoreConfigsFolder: %s", vcoreConfigsFolder) + + if err := os.Mkdir(vcoreConfigsFolder, 0755); os.IsExist(err) { + glog.V(100).Infof("%s folder already exists", vcoreConfigsFolder) + } + }) + + It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.DTPONamespace), + Label("smo"), VerifyDTPONamespaceExists) + + It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.KialiNamespace), + Label("smo"), VerifyKialiNamespaceExists) + + It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.IstioNamespace), + Label("smo"), VerifyIstioNamespaceExists) + + It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.SMONamespace), + Label("smo"), VerifyServiceMeshNamespaceExists) + + It("Verifies Distributed Tracing Platform Operator deployment succeeded", + Label("smo"), reportxml.ID("59495"), VerifyDTPODeployment) + + It("Verifies Kiali deployment succeeded", + Label("smo"), reportxml.ID("59496"), VerifyKialiDeployment) + + It("Verifies Service Mesh deployment succeeded", + Label("smo"), reportxml.ID("73732"), VerifyServiceMeshDeployment) + + It("Verifies Service Mesh configuration procedure succeeded", + Label("smo"), reportxml.ID("59502"), VerifyServiceMeshConfig) + }) +} + // VerifyDTPONamespaceExists asserts Distributed Tracing Platform Operator namespace exists. func VerifyDTPONamespaceExists(ctx SpecContext) { err := apiobjectshelper.VerifyNamespaceExists(APIClient, vcoreparams.DTPONamespace, time.Second) @@ -219,49 +266,3 @@ func VerifyServiceMeshConfig(ctx SpecContext) { Expect(err).ToNot(HaveOccurred(), "No %s labeled pods were found in %s namespace; %w", wasmBasicPodLabel, vcoreparams.IstioNamespace, err) } // func VerifyServiceMeshConfig (ctx SpecContext) - -// VerifyServiceMeshSuite container that contains tests for Service Mesh verification. -func VerifyServiceMeshSuite() { - Describe( - "Service Mesh Operator deployment and configuration validation", - Label(vcoreparams.LabelVCoreOperators), func() { - BeforeAll(func() { - By(fmt.Sprintf("Asserting %s folder exists", vcoreparams.ConfigurationFolderName)) - - homeDir, err := os.UserHomeDir() - Expect(err).To(BeNil(), fmt.Sprint(err)) - - vcoreConfigsFolder := filepath.Join(homeDir, vcoreparams.ConfigurationFolderName) - - glog.V(100).Infof("vcoreConfigsFolder: %s", vcoreConfigsFolder) - - if err := os.Mkdir(vcoreConfigsFolder, 0755); os.IsExist(err) { - glog.V(100).Infof("%s folder already exists", vcoreConfigsFolder) - } - }) - - It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.DTPONamespace), - Label("smo"), VerifyDTPONamespaceExists) - - It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.KialiNamespace), - Label("smo"), VerifyKialiNamespaceExists) - - It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.IstioNamespace), - Label("smo"), VerifyIstioNamespaceExists) - - It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.SMONamespace), - Label("smo"), VerifyServiceMeshNamespaceExists) - - It("Verifies Distributed Tracing Platform Operator deployment succeeded", - Label("smo"), reportxml.ID("59495"), VerifyDTPODeployment) - - It("Verifies Kiali deployment succeeded", - Label("smo"), reportxml.ID("59496"), VerifyKialiDeployment) - - It("Verifies Service Mesh deployment succeeded", - Label("smo"), reportxml.ID("73732"), VerifyServiceMeshDeployment) - - It("Verifies Service Mesh configuration procedure succeeded", - Label("smo"), reportxml.ID("59502"), VerifyServiceMeshConfig) - }) -} diff --git a/tests/system-tests/vcore/internal/vcorecommon/sriov-validation.go b/tests/system-tests/vcore/internal/vcorecommon/sriov-validation.go index 0c6e1f067..a381c478c 100644 --- a/tests/system-tests/vcore/internal/vcorecommon/sriov-validation.go +++ b/tests/system-tests/vcore/internal/vcorecommon/sriov-validation.go @@ -4,6 +4,8 @@ import ( "fmt" "time" + "github.com/openshift-kni/eco-goinfra/pkg/reportxml" + "github.com/openshift-kni/eco-goinfra/pkg/clusteroperator" "github.com/openshift-kni/eco-goinfra/pkg/nodes" "github.com/openshift-kni/eco-goinfra/pkg/sriov" @@ -14,11 +16,26 @@ import ( "github.com/golang/glog" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/openshift-kni/eco-goinfra/pkg/reportxml" . "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreinittools" "github.com/openshift-kni/eco-gotests/tests/system-tests/vcore/internal/vcoreparams" ) +// VerifySRIOVSuite container that contains tests for SR-IOV verification. +func VerifySRIOVSuite() { + Describe( + "SR-IOV Operator deployment and configuration validation", + Label(vcoreparams.LabelVCoreOperators), func() { + It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.SRIOVNamespace), + Label("sriov"), VerifySRIOVNamespaceExists) + + It("Verifies SR-IOV Operator deployment succeeded", + Label("sriov"), reportxml.ID("60041"), VerifySRIOVDeployment) + + It("Verifies SR-IOV configuration procedure succeeded", + Label("sriov"), reportxml.ID("60088"), VerifySRIOVConfig) + }) +} + // VerifySRIOVNamespaceExists asserts Distributed Tracing Platform Operator namespace exists. func VerifySRIOVNamespaceExists(ctx SpecContext) { err := apiobjectshelper.VerifyNamespaceExists(APIClient, vcoreparams.SRIOVNamespace, time.Second) @@ -175,19 +192,3 @@ func VerifySRIOVConfig(ctx SpecContext) { _, err = clusteroperator.WaitForAllClusteroperatorsAvailable(APIClient, 60*time.Second) Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("Error waiting for all available clusteroperators: %v", err)) } // func VerifySRIOVConfig (ctx SpecContext) - -// VerifySRIOVSuite container that contains tests for SR-IOV verification. -func VerifySRIOVSuite() { - Describe( - "SR-IOV Operator deployment and configuration validation", - Label(vcoreparams.LabelVCoreOperators), func() { - It(fmt.Sprintf("Verifies %s namespace exists", vcoreparams.SRIOVNamespace), - Label("sriov"), VerifySRIOVNamespaceExists) - - It("Verifies SR-IOV Operator deployment succeeded", - Label("sriov"), reportxml.ID("60041"), VerifySRIOVDeployment) - - It("Verifies SR-IOV configuration procedure succeeded", - Label("sriov"), reportxml.ID("60088"), VerifySRIOVConfig) - }) -} From bfab5853927b3f50b6bed54a0c277ad8ffcfdf00 Mon Sep 17 00:00:00 2001 From: Elena German Date: Sat, 22 Jun 2024 13:16:05 -0400 Subject: [PATCH 5/5] bump vendors --- kubeconfig | 19 - .../pkg/monitoring/servicemonitor.go | 363 ++++++++++++++++++ vendor/modules.txt | 1 + 3 files changed, 364 insertions(+), 19 deletions(-) delete mode 100644 kubeconfig create mode 100644 vendor/github.com/openshift-kni/eco-goinfra/pkg/monitoring/servicemonitor.go diff --git a/kubeconfig b/kubeconfig deleted file mode 100644 index 1f0035ae1..000000000 --- a/kubeconfig +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: v1 -clusters: -- cluster: - certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURoekNDQW0rZ0F3SUJBZ0lJYnk5akVHV3QvWGd3RFFZSktvWklodmNOQVFFTEJRQXdKakVrTUNJR0ExVUUKQXd3YmFXNW5jbVZ6Y3kxdmNHVnlZWFJ2Y2tBeE56RTROalF4TkRNek1CNFhEVEkwTURZeE56RTJNak0xTTFvWApEVEkyTURZeE56RTJNak0xTkZvd016RXhNQzhHQTFVRUF3d29LaTVoY0hCekxtdHVhUzF4WlMwMk9TNXNZV0l1ClpXNW5MbkprZFRJdWNtVmthR0YwTG1OdmJUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0MKZ2dFQkFNSHNHdEFjVDJkamZ2WFM1SjFYOEI5MnU0VTZKSVI2dnZBU3phZGpveFhqUmsrb2xYdHFmU1BBOFJWcQovUWF5U1dyVGNPWDNlcE53M3c0MTA5dkEzMW1ZbU83M2Y3bjVUUk40OXUwU3BxdTFTODRuSGlNbEtGR0VlR2RhCnFKRllPMldYYTB3ekMwT1FkSU5zK0F4TzZBeGVvVHpjcmxHdGZRZG40RVdYU0orSFhkc0hYdzZtbFpDOFRzQ0oKZGd4djNnZktlS3Q3VTVKb0l0a2Q2aVRGdlRLV0todGFIaHNzNjVmZ0xNZjdSRXZ1QkZLN2x6K1pQT0pLclZOegpwZ25UTWROUVBpb1JpREtlOEo3T2p0Nmo5SG5vV3lKN3MzM3JqRjZxdmhlckUveWxWUWd5Q28wcEFQUVl1SGRmCjU0ZVUycE83T0tmTEVzS0VrOU45NHZzV1ZCRUNBd0VBQWFPQnF6Q0JxREFPQmdOVkhROEJBZjhFQkFNQ0JhQXcKRXdZRFZSMGxCQXd3Q2dZSUt3WUJCUVVIQXdFd0RBWURWUjBUQVFIL0JBSXdBREFkQmdOVkhRNEVGZ1FVRGp5dwo5czMzdndYWlZYbVhQd1k2N2Fsa3VPQXdId1lEVlIwakJCZ3dGb0FVaU02UkZTQnYybE1ZMzVFcGFucjV2UzIwCm10SXdNd1lEVlIwUkJDd3dLb0lvS2k1aGNIQnpMbXR1YVMxeFpTMDJPUzVzWVdJdVpXNW5MbkprZFRJdWNtVmsKYUdGMExtTnZiVEFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBZndiRUM3ZE1kVE5MV24zRWozdkNCdDJudWs5awpBeFZwNDdLN3Y4elhobzIrTVlqdklML1FTbXAraGh6MVRzYXZQZ3lIMHlZdDNmZitoZWRCNzlGa3pha1ozQitJCnRUWXRxN0RGUHByUHNqUldiYWpteWFGWlo4UjFiOE9uZ0RRNVRFTWNseGxwM095eURlQjQ5U3BPQWs1RU0zK2MKRWpMWjlmeVVnZnlrbENNenV6MDB0TkhkSjNUdWJRYWZCVHp0MXYyQlBES2lDelZ3cmZidTZVL3d6WTJuaXVOWApWcGJQczAzT25QMldWSk13cU5IUS93THR5NDNHZlR3RHJsQXk3ZExwZ3AvdERkRHZJTkIyYVVZUVR2K2kxQnZyCnRONXd5UlEyVUlDS2R4RXJ3bGUrR21KRmlTZXRHZ1FCamQ4dWg5dTVmOGtSOGFFR0RwVnE4NzMrOEE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlERERDQ0FmU2dBd0lCQWdJQkFUQU5CZ2txaGtpRzl3MEJBUXNGQURBbU1TUXdJZ1lEVlFRRERCdHBibWR5ClpYTnpMVzl3WlhKaGRHOXlRREUzTVRnMk5ERTBNek13SGhjTk1qUXdOakUzTVRZeU16VXlXaGNOTWpZd05qRTMKTVRZeU16VXpXakFtTVNRd0lnWURWUVFEREJ0cGJtZHlaWE56TFc5d1pYSmhkRzl5UURFM01UZzJOREUwTXpNdwpnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDN1piYlR4Q0Qwb2xMSnhGQ3lsSGNCCk1UNk42QlZhM1ZGSjYxSmo3eWhIcUtaUFNGTktMMDhrZFA2UkhlZ1hOOEtkeEZUYkxZSDM2cW1CRkJ4L2VLeloKd1NuWjR1cktUcVUrNEw2VndRUmI5bkZRTTFyRVkyeldEM2ozZjlHYS81TEZsRlpReXJEZ0JNMEJNWUZzam1hbAp1dkJsekIwK082TXhONEZuL1R6dkZaRzBoblVjc1dkUXM3SmJnWlFXK2xZQm5ZTWwremdvTU5LczJuak5HdUIrCkRUc25kaW9RLzJuZHljSDhBM200UW1HVytCR0NOaTRYdmw4N1l6eTB2SFBhUHVNMDhxNGZCcWxpb2o0amRpejMKZkJLWUhaSmQ5bFZmWkpWdWNoTkVuRjcrZTcwRWdYcEtiSjF5cjVSTUxIVzEzMGFsL1NBN0ZCNjhzMWc5MWNHNQpBZ01CQUFHalJUQkRNQTRHQTFVZER3RUIvd1FFQXdJQ3BEQVNCZ05WSFJNQkFmOEVDREFHQVFIL0FnRUFNQjBHCkExVWREZ1FXQkJTSXpwRVZJRy9hVXhqZmtTbHFldm05TGJTYTBqQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUEKWlM5dXRRRWM5WmN2N0RCdjZXMXRhTXY2ak1xR0c2bENwM0hrWlRlT080TThlMnhudlpBMmxjaklaajJ0OW5rMgpkdTAzQm9rQzNxeS9XenhBTTZRM094YUh4Tk5GK0psYzdJUUo3a3hKak5pL0krKy82cktPemdmcytZT1dFLzRWCjgrS1RUUEUrQmhUZ0FXTjZ6OGlMNWdwZzZFZWtOTlFJSlJEK0FrQ1dNQkNlZEdrSHpvS1ZlR1VRbFRVQUlCOWcKbFdORUpLUDgrTHJ5dkx1UnZMaGszSGlZS0k3NUdXUExtVHF5ajk0NnJhU0R4WXdPUStaOHEvSStuWkNkN3d4TAozNDlsK3lxaXp2b0dWaGJPTjFBNFQyM0YwQnZrRURFUXJpa3pLb3BSQStYd2NaQklCU3Y3cVh4ZU1ZZkg0Y01qCnlUUEY4M1crUVJFa1lEazZWa3NxalE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEUURDQ0FpaWdBd0lCQWdJSUp3SWh0cEVYdU9jd0RRWUpLb1pJaHZjTkFRRUxCUUF3UGpFU01CQUdBMVVFCkN4TUpiM0JsYm5Ob2FXWjBNU2d3SmdZRFZRUURFeDlyZFdKbExXRndhWE5sY25abGNpMXNiMk5oYkdodmMzUXQKYzJsbmJtVnlNQjRYRFRJME1EWXhOekUyTURZMU1Gb1hEVE0wTURZeE5URTJNRFkxTUZvd1BqRVNNQkFHQTFVRQpDeE1KYjNCbGJuTm9hV1owTVNnd0pnWURWUVFERXg5cmRXSmxMV0Z3YVhObGNuWmxjaTFzYjJOaGJHaHZjM1F0CmMybG5ibVZ5TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF3U3N0VXUxYmVEdlgKMitkTFd3aUl2YkZ5dlZiQXYxUlJnZUlNY3M3ZUk5TWduZzhQVWRKblZRSXJHMjN3ZCtHR2dENTc5UEpWbUV4ZAo0dEZzb1laT0RvRFhCU214ZFhTUkFhelVoRWRsd1RjRFdreUJIWWtJRmM0bnVXajdaZHorTWxUU056RlkwZjVFCmhTTEs2TldZSnBqM3NDS1pXVXF0OGFYNUlTZ2xzWk5VMTRxdHVTbkZOZU90SzZ2RjVqZGZmTWVDUFNOS0J2VW0KVjlzQzYzaVRFMm5kb0k4OFpYczV5QTFlWnJhR1dpNEp6dmw5a0U0UnZySml3bHlhK2NUUHlMdEZNWmZxS3RWcwo1RW8wbjhGdEFzczJUL21OdTBwdDk0MGwyRlJwN2UyMy9SQTNTV1U4enZRZFo5ejU5aWxxZFBhcFlyZ3pOMU9UCnhIdVYxeHEvOVFJREFRQUJvMEl3UURBT0JnTlZIUThCQWY4RUJBTUNBcVF3RHdZRFZSMFRBUUgvQkFVd0F3RUIKL3pBZEJnTlZIUTRFRmdRVUo5RnZMU0Q5emFSakNuVCszVTFUbERweEpmRXdEUVlKS29aSWh2Y05BUUVMQlFBRApnZ0VCQURYNUh1V29JdXRlQThzR0Z4dmZpUTNjeDVCeHR0ckQwK3FIY0tOZWZEMk5aNXZpSERpdnFIZjRINzN3Cld6L0tuaEc2ZXU4N2g3KzBGeGNlZ0N3NGZyeHY4ZTIwaDBKcHhGdXIxWGVuWi9WVVZBK3V5dkhKOVoybXkwZkQKTitCbUp3SkFxZGlrMUt4VnhCSTRwYU15alhmVVduSWp1Qis5aUFkYjRMWkMvUTlxeFY2ZGtON1RCTzhHSmVmSgp6NGFJNnRzaDY4Ukhsem9sL3VzMkZXQnNtQW82Y0pPeGZJRVQ2emxiK1A4S29mLy8xZ0VXT282RVhjYUs4Vk0zCkFhY2tPTG5ZaVplbVNieFBqUmc3dzIxbWh6Zk0vMWx3bDhBbVU4MlRVVldLNUNzYmJkaks3L25rVktCRE5vY00KYkJtYmlwdGFmSUFYQmtEdmdML2VIa1Zsd3JNPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEVERDQ0FqU2dBd0lCQWdJSVZNcUhacEhiWWxRd0RRWUpLb1pJaHZjTkFRRUxCUUF3UkRFU01CQUdBMVVFCkN4TUpiM0JsYm5Ob2FXWjBNUzR3TEFZRFZRUURFeVZyZFdKbExXRndhWE5sY25abGNpMXpaWEoyYVdObExXNWwKZEhkdmNtc3RjMmxuYm1WeU1CNFhEVEkwTURZeE56RTJNRFkxTVZvWERUTTBNRFl4TlRFMk1EWTFNVm93UkRFUwpNQkFHQTFVRUN4TUpiM0JsYm5Ob2FXWjBNUzR3TEFZRFZRUURFeVZyZFdKbExXRndhWE5sY25abGNpMXpaWEoyCmFXTmxMVzVsZEhkdmNtc3RjMmxuYm1WeU1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0MKQVFFQXRJK3pHSXRFR05uL1o2L3RTdWMxZkNzZ2dPeWFoaVU4eVcxVFAvQ0FLWDRRLzNtVzdteXRpUWxzdGlxNApZcStzbllyaUxaQ2o2WDBNaUZWNmp3cTF3aW5JbUNNZnBGY0lSUFNYckw1eGZZcHJBUWFXY2ZPcU1xa2lubllSCjFwRkNhZE95cFZaMUdsOGNNM3pRTmRBOEozVXFDbS9Cc0Nzd2ttcytEMHVueFEwdHlSNHM5RVN2eWhtc2xQUTEKYWVCK0VDMWhlQ3gyTFpTdENoS1QzdU0vZFBvRnV0bndCUDJ5Z3lHWkNPZmVYbXdUZ0s2MzEzbE02WHl3RFlldgpaSGNmNURRckNTUCsvYllNZVVqakZQOElIeEhrOXZETm9TbEw1cW9CM1ZJY1RTRGpnc3V3TGkxbkNEVldURWtPCkcxaFNMNCtHMGthUE1UTmxTakdkdDZzLzhRSURBUUFCbzBJd1FEQU9CZ05WSFE4QkFmOEVCQU1DQXFRd0R3WUQKVlIwVEFRSC9CQVV3QXdFQi96QWRCZ05WSFE0RUZnUVVmMWZaLzBhclU1Q1RPUm5wbC9TYUFaZWNNM3N3RFFZSgpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFEMlQzNlJSV0YxcXJJQ3g4MERKV1V4ZUNQVHVubStaSk1JMk4rZkFpSHBFCkZQK09ZbTlaVndWSW5YdEd5V2J6c2FadjZXM2JVRUxCLzVsQ3RKbGxIS0twK1pqcUxidHBIc3dBbWd1bExMYVEKQ3JnQVVrVUJOVTNPb0Vqb1lTMHo5RHdITW9GRSsyMEJKTWo1QXlzckFSRkZsdFhHdDdmZHd1VDdkbHZ0VDRnRQpUTzJ0QUdSdDRKNHdGUmlNQXpOaUdiV0NHa2FzcHZkMk5raEFzVFpiQTQ4UFJIaWxLTVd0K2NRU283d3FzQ0dpCm5POGxKdjIydUd2V1ZzWlg0Y2MrRDBTL3hicWd3Rk1UOFJ4VVV3S2ZlSFl2NzFmRWhtZ3FPeFVPa2U0WDg3OTUKdE5JME5ZMzVIVWpjWFJVNnVkbU9oZDJIRWFMMDM5ZFBjckRzaE1RSWxxRT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRE1UQ0NBaG1nQXdJQkFnSUhGaDBUMzVLL3RqQU5CZ2txaGtpRzl3MEJBUXNGQURBM01SSXdFQVlEVlFRTApFd2x2Y0dWdWMyaHBablF4SVRBZkJnTlZCQU1UR0d0MVltVXRZWEJwYzJWeWRtVnlMV3hpTFhOcFoyNWxjakFlCkZ3MHlOREEyTVRjeE5qQTJOVEJhRncwek5EQTJNVFV4TmpBMk5UQmFNRGN4RWpBUUJnTlZCQXNUQ1c5d1pXNXoKYUdsbWRERWhNQjhHQTFVRUF4TVlhM1ZpWlMxaGNHbHpaWEoyWlhJdGJHSXRjMmxuYm1WeU1JSUJJakFOQmdrcQpoa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXMzQWxhVnlyT1liT1A2TEF3b3pmR2VSdGJSaXE5NlNYCmtmdHdwUytlUG4xajRuUzRvYmF1VmhPTElKYzJYcTlLVnpGWFVCeEFXNXpVTWc3QVdvYkN6cnRMNElTNUdkNGsKNVZLcW9OV0N1d3A4cTdOb0ZJSE15S0M4dUllOEJuQjg4d3JyVzYyZCt3Rnp4YnlZQll6Sjlpc0xJNUpteVNaVApuOFFpcXQyamxJZklNY0lEZVVTN0NSOFZTL0FiaXhabCsxNVBEanpaZEFpR0JKdWFkNy9tc3RsR1VabWlYUHpUCjNYekZWdEpEWXhxUm9Cb0lTLzQzUVRCcmgyd3VaWWdTVWhmRmtiWVM5c00zeGgrOXNBVmUvVTRVUjhOWGs1RlIKdkNtS1JIZ2F4QjFJT0liUDNMeFRpaU5oazI4ZW9ucHhYdnFXMEtvNEw3b055SjloWTNWR1J3SURBUUFCbzBJdwpRREFPQmdOVkhROEJBZjhFQkFNQ0FxUXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QWRCZ05WSFE0RUZnUVU3bDJBClRtNFRVVXM1bHNhUHhTSXkrZ1crTDNvd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFDWlprWVB0ZXNpdGUxMGMKWmk0Q1lMTFJCSFl6QXhBWlFBYUliSCtIckI4M2dXWnRkTzVzaElhY3Y2ejZPSUVvNnhBZVFJaGpyM05YMDA0SApSY3poOC9mV2ZEMzVuR3lUeTBYZ3V1cE5LQnluSElHenQ1dUxqZXFQVUZxOG9ZU0hoZDExS0RBZlhjbU83Q3YrCjZ5Q1lKdllSTGhJZmtnbFpHUm50dHBwYWl6YnFhVG1QWG5wdXNMNWo5RnNxbEZxc08rOTFYQzhKeUM4RkhkTGgKRmw0TVNQRFJZeGt2aG9zUmh2UC9TQlhJR28zS2Q4eCtZWWpCTThDQVFwNEJSMi91b3FKSEd6Z1NwVmNwWDlpSApPUzA0OExYOElRMXdKcTJlc0lxQUUycFFtS1IreXpkc2RlS0d5UHhaZDRjdGJnL1I5emdNVUsyTVZhL2hDTS93CmZLVkt5azQ9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K - server: https://api.kni-qe-69.lab.eng.rdu2.redhat.com:6443 - name: kni-qe-69 -contexts: -- context: - cluster: kni-qe-69 - user: admin - name: admin -current-context: admin -kind: Config -preferences: {} -users: -- name: admin - user: - client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURaekNDQWsrZ0F3SUJBZ0lJSHJqWVlURFVTRzR3RFFZSktvWklodmNOQVFFTEJRQXdOakVTTUJBR0ExVUUKQ3hNSmIzQmxibk5vYVdaME1TQXdIZ1lEVlFRREV4ZGhaRzFwYmkxcmRXSmxZMjl1Wm1sbkxYTnBaMjVsY2pBZQpGdzB5TkRBMk1UY3hOakEyTlRGYUZ3MHpOREEyTVRVeE5qQTNNemxhTURBeEZ6QVZCZ05WQkFvVERuTjVjM1JsCmJUcHRZWE4wWlhKek1SVXdFd1lEVlFRREV3eHplWE4wWlcwNllXUnRhVzR3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUN4N0xOamsyMmFBd1BxRkRPYmM2aDVWRk1OckRJT2JQa1Vub0MxZ3hFRQpIZFNSNUZkQVVoNm50M3lsM1NkWEdWUmcyUUc0RVlRaUpqVGN5KzRST1BXcmY3dVh2d211cm5yblp4M1hXeWluCjN0aGU5K3RDMTd4ZlA3alh5T2xlZm9kRU5lOEJwNnJQdldDTHk3NC9tQlRzcEh6Rnk4cW5POCtRLzRqTE5kb2IKbnNSNUYxVFdoVE00QUQ5Y2lCZHRwS2FXaWNVcU9yNlFTWVE5cWFtYXBScXM1ZzB1TldLMFY4a1RsK1RYWXVvTApnQjdoL3NCVE41QkFYV01ldHdlOUl0YVJrUGhwQUxWbFlmM1Jkem9XSlUvcUFXR0VKeU5zSkZFSHc4UjFMY29QCmZhUVQ2enA5NERpS3RsZ2pJTnNyT3lxRkNWU1EzaFhpR2JZSEw2SHZxNGc1QWdNQkFBR2pmekI5TUE0R0ExVWQKRHdFQi93UUVBd0lGb0RBZEJnTlZIU1VFRmpBVUJnZ3JCZ0VGQlFjREFRWUlLd1lCQlFVSEF3SXdEQVlEVlIwVApBUUgvQkFJd0FEQWRCZ05WSFE0RUZnUVVhMEZnMUxtU1ZRREUzcXQ2OEllSGI5Zi9STlV3SHdZRFZSMGpCQmd3CkZvQVU1L1Z6Wm5NTk1mUUYyZkh0bXZhRk1jWWF6Yzh3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUtrTWtJNXgKcGREdWRiRlAxWWhXU3dPbFpDZlBYY2U2WGVETU1BRHdTb0dhUHppZmk0bHErVXNvbUd0QnM5ZnU1bU5yUXlHQwpYbjZYclgvNDloRENpQ1Q5ZXlpMHlaYjlIVXF2ajdiMlBwZ0lTUnArbVJDc21jdHZKT1NabXp4bmlxUy9jdkx1CjBRaUV0MHdMaEs5cTlEdEwwUGpPc2RTcUhtbXdVLzNlT0toTXJYcC9ydkVvaVZoRmZEcDV2NDFOcWRyZUhnaGUKK1RkN0ZaZTB6VFhMblllSGIzTkl3WXRSL3hWbUptTEVmL1o5WnZ4Rk84YXBDdjBPWTFpdFFJQk5ha010bHhkTgpVMzk1cDk2Q2QrOEg2dDNmUmtXTXQvaFB5YkZKek5wLzhtVEUxbzRPUk01bWR2Y0doZDdGaTdiaVI1Y3ZkWG5kCi8vejNWYW5VbHFSQWxCWT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= - client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBc2V5elk1TnRtZ01ENmhRem0zT29lVlJURGF3eURtejVGSjZBdFlNUkJCM1VrZVJYClFGSWVwN2Q4cGQwblZ4bFVZTmtCdUJHRUlpWTAzTXZ1RVRqMXEzKzdsNzhKcnE1NjUyY2QxMXNvcDk3WVh2ZnIKUXRlOFh6KzQxOGpwWG42SFJEWHZBYWVxejcxZ2k4dStQNWdVN0tSOHhjdktwenZQa1ArSXl6WGFHNTdFZVJkVQoxb1V6T0FBL1hJZ1hiYVNtbG9uRktqcStrRW1FUGFtcG1xVWFyT1lOTGpWaXRGZkpFNWZrMTJMcUM0QWU0ZjdBClV6ZVFRRjFqSHJjSHZTTFdrWkQ0YVFDMVpXSDkwWGM2RmlWUDZnRmhoQ2NqYkNSUkI4UEVkUzNLRDMya0UrczYKZmVBNGlyWllJeURiS3pzcWhRbFVrTjRWNGhtMkJ5K2g3NnVJT1FJREFRQUJBb0lCQUNlZThDdWlidXUyOUM0eQpKWFBlZzR2UkxWV0VIUGw5WnRJaW9jTEoxd1kxcGxwK29MZGdFaGVERXF6VTNLZldxaVdPN1lVUjBYelJTVUJKCjRVL1FnVlNaY3lyTmpkaHFYbEFkZEZXNnBRa001TjN4RTJDbExmdC84eWVLUS8yWTY0SlRDRkEwQ0NPT3BtczcKQ2JpYm96MDNPOW5JRWU2L3NPODNHRDA0VnNPRGJtVDBUbWFxT2czV1lpeDlUMVhFemNuLzV6QnJ2aTh3QXdrRgpDU1M2UWZPMWVQSXVnRTJxbWIrL1lTMFBEc1ZWMVNmTkY5TE9wSnFFVFo5R2k1ZzJNU1AwN2Uzdm8xUTJtSDR2CnpIL1N6dW9xd0xsRUh0V1VBZjgwd3RSc3ZZNkFtSEJHbzgwT25GLzByc2M5K3F4eE96VTNYRThpcUVPa09oMysKL3k5Skora0NnWUVBMEhWem15R0hzWEFhL0REWE9WWHZFZ09oUXlsWHNZZHFSNVdMdjUvclAyZ2hhdTF1T0dQWApvSjdobjljSlcvWGtSdkZyWUxVUkRTS1VycmdRdFRwb0NRZUMzRnVyekY3MUdnSElyd2FtSUhvOXlwUm9YU25vCmZ0WlhwL0FmREdma1FUSnJiM3VkTzJQUy9kTWhPb1EyVk5ON3cwTFNIVlJmckl6VGFtYXRQdGNDZ1lFQTJvQ08KdU5rVVhrK1dyUzBJZVAvMHFzMWxsN2JQZjhaSC9aZzVHYkpCVmJWazg0TFpTMjRHU2s0SDVDb3pHMjB6UUxRbwpsblJBMWE1aFBpVFV5cm45TU8weXZQWlRLME9sZDFzemtNa2g5UUdsQkVvam1kbGJLRlhjTTE5OXgxRFdJaU01CnhDTk5kQnV0bDhkeFRETlJMbWtQemI1NGRUS3RqVDdYRG51dzMyOENnWUVBcW93Tkl4UlJvZmZuL0FBeGRYVTYKL08vL1ZhVlRXNmxBYUlTUEt4MjVKODBYMmhXYW9ZUDkvQ2xBeXJieHIwMERrSThmbktWRzZBb3N2cTFVN2hCMAo0VDVGNytjSUxWSmJFUVg0bkVuQ1RMdjJKZkU1V1U5YUtidFBSOVNLY21ubE12bi9MOXhnalNCa2xNblJXOENqCmVzN3phSk1ZdUdvNVJFQ0xEM2dsc1UwQ2dZQmdjemtNN1gzcE41YWFjUE41ZmZxQlh0TkdpZ0xFTTBGWjl0VFYKdS9MTkk1b2hSNVFsa0xha0hCZXRwdGNTZHp5VmhqRVlZTTZ4eEJ6V3NxbGZwNFBWRWc5QWpEY2dOT2NZYmFDdwplNmhLbjJRNUpZVGJoNitPZVlBUENVcmJMWnFvVFFaVnh3T01paDh4alc4OHBMWmtGeXBMdHBVem5xQXZaaHJHCklPRnRid0tCZ1FDSG1yeThSZG1GM2hPVkVjd01Ud1grY1ZUSUJXMG9Ha0dLVWJxUHNXakllTVNDOVdZaHdqaTEKVjFJclZBSEZxaXo2SjJtSDlCUVNtSVhMU1FVRzNIR3Yxd3FKS2s4aWQ4ZmVxdGVMekZmQnJOMjJQa2d5ckE3RQpWYWs2TGlQS2hWYjdKWUpuTWN4dnMrbHRCRVRPMGsvRVNubXVhS2NJekxyb2dLekdpS0t4OGc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= diff --git a/vendor/github.com/openshift-kni/eco-goinfra/pkg/monitoring/servicemonitor.go b/vendor/github.com/openshift-kni/eco-goinfra/pkg/monitoring/servicemonitor.go new file mode 100644 index 000000000..b6b8601a5 --- /dev/null +++ b/vendor/github.com/openshift-kni/eco-goinfra/pkg/monitoring/servicemonitor.go @@ -0,0 +1,363 @@ +package monitoring + +import ( + "context" + "fmt" + + monv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + + "github.com/golang/glog" + "github.com/openshift-kni/eco-goinfra/pkg/clients" + "github.com/openshift-kni/eco-goinfra/pkg/msg" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + goclient "sigs.k8s.io/controller-runtime/pkg/client" +) + +// Builder provides a struct for serviceMonitor object from the cluster +// and a serviceMonitor definition. +type Builder struct { + // serviceMonitor definition, used to create the serviceMonitor object. + Definition *monv1.ServiceMonitor + // Created serviceMonitor object. + Object *monv1.ServiceMonitor + // Used to store latest error message upon defining or mutating serviceMonitor definition. + errorMsg string + // api client to interact with the cluster. + apiClient goclient.Client +} + +// NewBuilder creates a new instance of Builder. +func NewBuilder( + apiClient *clients.Settings, name, nsname string) *Builder { + glog.V(100).Infof( + "Initializing new serviceMonitor structure with the following params: "+ + "name: %s, namespace: %s", name, nsname) + + if apiClient == nil { + glog.V(100).Infof("serviceMonitor 'apiClient' cannot be empty") + + return nil + } + + builder := &Builder{ + apiClient: apiClient.Client, + Definition: &monv1.ServiceMonitor{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: nsname, + }, + }, + } + + if name == "" { + glog.V(100).Infof("The name of the serviceMonitor is empty") + + builder.errorMsg = "serviceMonitor 'name' cannot be empty" + + return builder + } + + if nsname == "" { + glog.V(100).Infof("The nsname of the serviceMonitor is empty") + + builder.errorMsg = "serviceMonitor 'nsname' cannot be empty" + + return builder + } + + return builder +} + +// Pull pulls existing serviceMonitor from cluster. +func Pull(apiClient *clients.Settings, name, nsname string) (*Builder, error) { + glog.V(100).Infof("Pulling existing serviceMonitor name %s in namespace %s from cluster", + name, nsname) + + if apiClient == nil { + glog.V(100).Infof("The apiClient is empty") + + return nil, fmt.Errorf("serviceMonitor 'apiClient' cannot be empty") + } + + builder := Builder{ + apiClient: apiClient.Client, + Definition: &monv1.ServiceMonitor{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: nsname, + }, + }, + } + + if name == "" { + glog.V(100).Infof("The name of the serviceMonitor is empty") + + return nil, fmt.Errorf("serviceMonitor 'name' cannot be empty") + } + + if nsname == "" { + glog.V(100).Infof("The namespace of the serviceMonitor is empty") + + return nil, fmt.Errorf("serviceMonitor 'nsname' cannot be empty") + } + + if !builder.Exists() { + return nil, fmt.Errorf("serviceMonitor object %s does not exist in namespace %s", name, nsname) + } + + builder.Definition = builder.Object + + return &builder, nil +} + +// Get fetches the defined serviceMonitor from the cluster. +func (builder *Builder) Get() (*monv1.ServiceMonitor, error) { + if valid, err := builder.validate(); !valid { + return nil, err + } + + glog.V(100).Infof("Getting serviceMonitor %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + serviceMonitorObj := &monv1.ServiceMonitor{} + err := builder.apiClient.Get(context.TODO(), goclient.ObjectKey{ + Name: builder.Definition.Name, + Namespace: builder.Definition.Namespace, + }, serviceMonitorObj) + + if err != nil { + return nil, err + } + + return serviceMonitorObj, nil +} + +// Create makes a serviceMonitor in the cluster and stores the created object in struct. +func (builder *Builder) Create() (*Builder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Creating the serviceMonitor %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + var err error + if !builder.Exists() { + err = builder.apiClient.Create(context.TODO(), builder.Definition) + if err == nil { + builder.Object = builder.Definition + } + } + + return builder, err +} + +// Delete removes serviceMonitor from a cluster. +func (builder *Builder) Delete() (*Builder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Deleting the serviceMonitor %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + if !builder.Exists() { + glog.V(100).Infof("serviceMonitor %s in namespace %s cannot be deleted"+ + " because it does not exist", + builder.Definition.Name, builder.Definition.Namespace) + + builder.Object = nil + + return builder, nil + } + + err := builder.apiClient.Delete(context.TODO(), builder.Definition) + + if err != nil { + return builder, fmt.Errorf("can not delete serviceMonitor: %w", err) + } + + builder.Object = nil + + return builder, nil +} + +// Exists checks whether the given serviceMonitor exists. +func (builder *Builder) Exists() bool { + if valid, _ := builder.validate(); !valid { + return false + } + + glog.V(100).Infof("Checking if serviceMonitor %s exists in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + var err error + builder.Object, err = builder.Get() + + return err == nil || !k8serrors.IsNotFound(err) +} + +// Update renovates the existing serviceMonitor object with serviceMonitor definition in builder. +func (builder *Builder) Update() (*Builder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Updating serviceMonitor %s in namespace %s", + builder.Definition.Name, builder.Definition.Namespace) + + err := builder.apiClient.Update(context.TODO(), builder.Definition) + + if err != nil { + glog.V(100).Infof( + msg.FailToUpdateError("serviceMonitor", builder.Definition.Name, builder.Definition.Namespace)) + + return nil, err + } + + builder.Object = builder.Definition + + return builder, nil +} + +// WithEndpoints sets the serviceMonitor operator's endpoints. +func (builder *Builder) WithEndpoints( + endpoints []monv1.Endpoint) *Builder { + glog.V(100).Infof( + "Adding endpoints to serviceMonitor %s in namespace %s; endpoints %v", + builder.Definition.Name, builder.Definition.Namespace, endpoints) + + if valid, _ := builder.validate(); !valid { + return builder + } + + if len(endpoints) == 0 { + glog.V(100).Infof("'endpoints' argument cannot be empty") + + builder.errorMsg = "'endpoints' argument cannot be empty" + + return builder + } + + builder.Definition.Spec.Endpoints = endpoints + + return builder +} + +// WithLabels redefines the serviceMonitor with labels. +func (builder *Builder) WithLabels(labels map[string]string) *Builder { + if valid, _ := builder.validate(); !valid { + return builder + } + + glog.V(100).Infof("Defining serviceMonitor with labels: %v", labels) + + if len(labels) == 0 { + glog.V(100).Infof("labels can not be empty") + + builder.errorMsg = "labels can not be empty" + + return builder + } + + for key := range labels { + if key == "" { + glog.V(100).Infof("The 'labels' key cannot be empty") + + builder.errorMsg = "can not apply a labels with an empty key" + + return builder + } + } + + builder.Definition.Labels = labels + + return builder +} + +// WithSelector redefines the serviceMonitor with selector. +func (builder *Builder) WithSelector(selector map[string]string) *Builder { + if valid, _ := builder.validate(); !valid { + return builder + } + + glog.V(100).Infof("Defining serviceMonitor with selector: %v", selector) + + if len(selector) == 0 { + glog.V(100).Infof("selector can not be empty") + + builder.errorMsg = "selector can not be empty" + + return builder + } + + for key := range selector { + if key == "" { + glog.V(100).Infof("The 'selector' key cannot be empty") + + builder.errorMsg = "can not apply a selector with an empty key" + + return builder + } + } + + builder.Definition.Spec.Selector.MatchLabels = selector + + return builder +} + +// WithNamespaceSelector redefines the serviceMonitor with namespaceSelector. +func (builder *Builder) WithNamespaceSelector(namespaceSelector []string) *Builder { + if valid, _ := builder.validate(); !valid { + return builder + } + + glog.V(100).Infof("Defining serviceMonitor with namespaceSelector: %v", namespaceSelector) + + if len(namespaceSelector) == 0 { + glog.V(100).Infof("namespaceSelector can not be empty") + + builder.errorMsg = "namespaceSelector can not be empty" + + return builder + } + + builder.Definition.Spec.NamespaceSelector = monv1.NamespaceSelector{ + MatchNames: namespaceSelector, + } + + return builder +} + +// validate will check that the builder and builder definition are properly initialized before +// accessing any member fields. +func (builder *Builder) validate() (bool, error) { + resourceCRD := "ServiceMonitor" + + if builder == nil { + glog.V(100).Infof("The %s builder is uninitialized", resourceCRD) + + return false, fmt.Errorf("error: received nil %s builder", resourceCRD) + } + + if builder.Definition == nil { + glog.V(100).Infof("The %s is undefined", resourceCRD) + + return false, fmt.Errorf(msg.UndefinedCrdObjectErrString(resourceCRD)) + } + + if builder.apiClient == nil { + glog.V(100).Infof("The %s builder apiclient is nil", resourceCRD) + + return false, fmt.Errorf("%s builder cannot have nil apiClient", resourceCRD) + } + + if builder.errorMsg != "" { + glog.V(100).Infof("The %s builder has error message: %s", resourceCRD, builder.errorMsg) + + return false, fmt.Errorf(builder.errorMsg) + } + + return true, nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 0b3c5e30d..eabd9fa92 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -667,6 +667,7 @@ github.com/openshift-kni/eco-goinfra/pkg/machine github.com/openshift-kni/eco-goinfra/pkg/mco github.com/openshift-kni/eco-goinfra/pkg/metallb github.com/openshift-kni/eco-goinfra/pkg/metallb/mlbtypes +github.com/openshift-kni/eco-goinfra/pkg/monitoring github.com/openshift-kni/eco-goinfra/pkg/msg github.com/openshift-kni/eco-goinfra/pkg/nad github.com/openshift-kni/eco-goinfra/pkg/namespace