diff --git a/apis/vshn/v1/dbaas_vshn_mariadb.go b/apis/vshn/v1/dbaas_vshn_mariadb.go index 5a020151e2..eaafa06539 100644 --- a/apis/vshn/v1/dbaas_vshn_mariadb.go +++ b/apis/vshn/v1/dbaas_vshn_mariadb.go @@ -171,6 +171,10 @@ type XVSHNMariaDB struct { Status XVSHNMariaDBStatus `json:"status,omitempty"` } +func (v *XVSHNMariaDB) GetInstanceNamespace() string { + return fmt.Sprintf("vshn-mariadb-%s", v.GetName()) +} + // XVSHNMariaDBSpec defines the desired state of a VSHNMariaDB. type XVSHNMariaDBSpec struct { // Parameters are the configurable fields of a VSHNMariaDB. diff --git a/apis/vshn/v1/dbaas_vshn_redis.go b/apis/vshn/v1/dbaas_vshn_redis.go index f8dafcd250..49b795e2ac 100644 --- a/apis/vshn/v1/dbaas_vshn_redis.go +++ b/apis/vshn/v1/dbaas_vshn_redis.go @@ -2,6 +2,7 @@ package v1 import ( "fmt" + xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -166,6 +167,10 @@ type XVSHNRedis struct { Status XVSHNRedisStatus `json:"status,omitempty"` } +func (v *XVSHNRedis) GetInstanceNamespace() string { + return fmt.Sprintf("vshn-redis-%s", v.GetName()) +} + // XVSHNRedisSpec defines the desired state of a VSHNRedis. type XVSHNRedisSpec struct { // Parameters are the configurable fields of a VSHNRedis. diff --git a/apis/vshn/v1/vshn_minio.go b/apis/vshn/v1/vshn_minio.go index 881386ebc5..fd45a6861a 100644 --- a/apis/vshn/v1/vshn_minio.go +++ b/apis/vshn/v1/vshn_minio.go @@ -2,6 +2,7 @@ package v1 import ( "fmt" + xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -130,6 +131,10 @@ type XVSHNMinio struct { Status XVSHNMinioStatus `json:"status,omitempty"` } +func (v *XVSHNMinio) GetInstanceNamespace() string { + return fmt.Sprintf("vshn-minio-%s", v.GetName()) +} + // XVSHNMinioSpec defines the desired state of a VSHNMinio. type XVSHNMinioSpec struct { // Parameters are the configurable fields of a VSHNMinio. diff --git a/cmd/sliexporter.go b/cmd/sliexporter.go index 2ba0d51739..c3d2200eac 100644 --- a/cmd/sliexporter.go +++ b/cmd/sliexporter.go @@ -2,12 +2,14 @@ package cmd import ( "os" - "strconv" "time" + managedupgradev1beta1 "github.com/appuio/openshift-upgrade-controller/api/v1beta1" "github.com/go-logr/logr" "github.com/spf13/cobra" + vshnv1 "github.com/vshn/appcat/v4/apis/vshn/v1" "github.com/vshn/appcat/v4/pkg" + "github.com/vshn/appcat/v4/pkg/common/utils" maintenancecontroller "github.com/vshn/appcat/v4/pkg/sliexporter/maintenance_controller" "github.com/vshn/appcat/v4/pkg/sliexporter/probes" vshnkeycloakcontroller "github.com/vshn/appcat/v4/pkg/sliexporter/vshnkeycloak_controller" @@ -16,16 +18,20 @@ import ( vshnpostgresqlcontroller "github.com/vshn/appcat/v4/pkg/sliexporter/vshnpostgresql_controller" vshnrediscontroller "github.com/vshn/appcat/v4/pkg/sliexporter/vshnredis_controller" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/cluster" "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/metrics" "sigs.k8s.io/controller-runtime/pkg/metrics/server" ) type sliProber struct { - scheme *runtime.Scheme - metricsAddr, probeAddr string - leaderElect, enableVSHNPostgreSQL, enableVSHNRedis, enableVSHNMinio, enableMaintenanceStatus, enableKeycloak, enableMariaDB bool + scheme *runtime.Scheme + metricsAddr, probeAddr, serviceKubeConfig string + leaderElect bool } var s = sliProber{ @@ -39,21 +45,17 @@ var SLIProberCMD = &cobra.Command{ RunE: s.executeSLIProber, } +const ( + startupGraceMin = 10 +) + func init() { SLIProberCMD.Flags().StringVar(&s.metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") SLIProberCMD.Flags().StringVar(&s.probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") SLIProberCMD.Flags().BoolVar(&s.leaderElect, "leader-elect", false, "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") - SLIProberCMD.Flags().BoolVar(&s.enableVSHNPostgreSQL, "vshn-postgresql", getEnvBool("APPCAT_SLI_VSHNPOSTGRESQL"), - "Enable probing of VSHNPostgreSQL instances") - SLIProberCMD.Flags().BoolVar(&s.enableVSHNRedis, "vshn-redis", getEnvBool("APPCAT_SLI_VSHNREDIS"), - "Enable probing of VSHNRedis instances") - SLIProberCMD.Flags().BoolVar(&s.enableVSHNMinio, "vshn-minio", getEnvBool("APPCAT_SLI_VSHNMINIO"), - "Enable probing of VSHNMinio instances") - SLIProberCMD.Flags().BoolVar(&s.enableMaintenanceStatus, "vshn-track-oc-maintenance-status", getEnvBool("APPCAT_SLI_TRACK_OC_MAINTENANCE_STATUS"), - "Enable oc maintenance status observer. Will set the labels 'maintenance' accordingly.") - SLIProberCMD.Flags().BoolVar(&s.enableKeycloak, "vshn-keycloak", getEnvBool("APPCAT_SLI_VSHNKEYCLOAK"), "Enable probing of VSHNKeycloak instances") - SLIProberCMD.Flags().BoolVar(&s.enableMariaDB, "vshn-mariadb", getEnvBool("APPCAT_SLI_VSHNMARIADB"), "Enable probing of VSHNMariaDB instances") + SLIProberCMD.Flags().StringVar(&s.serviceKubeConfig, "service-kubeconfig", os.Getenv("SERVICE_KUBECONFIG"), + "Kubeconfig for the service cluster itself, usually only for debugging purpose. The sliprober should run on the service clusters and thus use the in-cluster-config.") } func (s *sliProber) executeSLIProber(cmd *cobra.Command, _ []string) error { @@ -74,8 +76,20 @@ func (s *sliProber) executeSLIProber(cmd *cobra.Command, _ []string) error { return err } + config, err := getServiceClusterConfig() + if err != nil { + return err + } + + scClient, err := client.New(config, client.Options{ + Scheme: pkg.SetupScheme(), + }) + if err != nil { + return err + } + maintenanceRecociler := &maintenancecontroller.MaintenanceReconciler{ - Client: mgr.GetClient(), + Client: scClient, } probeManager := probes.NewManager(log, maintenanceRecociler) @@ -86,74 +100,88 @@ func (s *sliProber) executeSLIProber(cmd *cobra.Command, _ []string) error { return err } - if s.enableVSHNPostgreSQL { + if utils.IsKindAvailable(vshnv1.GroupVersion, "XVSHNPostgreSQL", ctrl.GetConfigOrDie()) { + log.Info("Enabling VSHNPostgreSQL controller") if err = (&vshnpostgresqlcontroller.VSHNPostgreSQLReconciler{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), ProbeManager: &probeManager, - StartupGracePeriod: 15 * time.Minute, + StartupGracePeriod: startupGraceMin * time.Minute, PostgreDialer: probes.NewPostgreSQL, + ScClient: scClient, }).SetupWithManager(mgr); err != nil { log.Error(err, "unable to create controller", "controller", "VSHNPostgreSQL") return err } } - if s.enableVSHNRedis { + if utils.IsKindAvailable(vshnv1.GroupVersion, "XVSHNRedis", ctrl.GetConfigOrDie()) { log.Info("Enabling VSHNRedis controller") if err = (&vshnrediscontroller.VSHNRedisReconciler{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), ProbeManager: &probeManager, - StartupGracePeriod: 10 * time.Minute, + StartupGracePeriod: startupGraceMin * time.Minute, RedisDialer: probes.NewRedis, + ScClient: scClient, }).SetupWithManager(mgr); err != nil { log.Error(err, "unable to create controller", "controller", "VSHNRedis") return err } } - if s.enableVSHNMinio { + if utils.IsKindAvailable(vshnv1.GroupVersion, "XVSHNMinio", ctrl.GetConfigOrDie()) { log.Info("Enabling VSHNRedis controller") if err = (&vshnminiocontroller.VSHNMinioReconciler{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), ProbeManager: &probeManager, - StartupGracePeriod: 10 * time.Minute, + StartupGracePeriod: startupGraceMin * time.Minute, MinioDialer: probes.NewMinio, + ScClient: scClient, }).SetupWithManager(mgr); err != nil { log.Error(err, "unable to create controller", "controller", "VSHNRedis") return err } } - if s.enableKeycloak { + if utils.IsKindAvailable(vshnv1.GroupVersion, "XVSHNKeycloak", ctrl.GetConfigOrDie()) { log.Info("Enablign VSHNKeycloak controller") if err = (&vshnkeycloakcontroller.VSHNKeycloakReconciler{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), ProbeManager: &probeManager, - StartupGracePeriod: 10 * time.Minute, + StartupGracePeriod: startupGraceMin * time.Minute, + ScClient: scClient, }).SetupWithManager(mgr); err != nil { log.Error(err, "unable to create controller", "controller", "VSHNKeycloak") return err } } - if s.enableMaintenanceStatus { + if utils.IsKindAvailable(managedupgradev1beta1.GroupVersion, "UpgradeJob", config) { log.Info("Enable OC maintenance observer") - if err = maintenanceRecociler.SetupWithManager(mgr); err != nil { + serviceCluster, err := getServiceCluster(config) + if err != nil { + return err + } + if err = maintenanceRecociler.SetupWithManager(mgr, serviceCluster); err != nil { log.Error(err, "unable to create controller", "controller", "Maintenance Observer") return err } + err = mgr.Add(*serviceCluster) + if err != nil { + return err + } } - if s.enableMariaDB { + if utils.IsKindAvailable(vshnv1.GroupVersion, "XVSHNMariaDB", ctrl.GetConfigOrDie()) { log.Info("Enabling VSHNMariaDB controller") if err = (&vshnmariadbcontroller.VSHNMariaDBReconciler{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), ProbeManager: &probeManager, - StartupGracePeriod: 1 * time.Minute, + StartupGracePeriod: startupGraceMin * time.Minute, MariaDBDialer: probes.NewMariaDB, + ScClient: scClient, }).SetupWithManager(mgr); err != nil { log.Error(err, "unable to create controller", "controller", "VSHNMariadb") return err @@ -179,7 +207,39 @@ func (s *sliProber) executeSLIProber(cmd *cobra.Command, _ []string) error { return nil } -func getEnvBool(key string) bool { - b, err := strconv.ParseBool(os.Getenv(key)) - return err == nil && b +func getServiceCluster(config *rest.Config) (*cluster.Cluster, error) { + serviceCluster, err := cluster.New(config, func(o *cluster.Options) { + o.Scheme = pkg.SetupScheme() + }) + return &serviceCluster, err +} + +// getServiceClusterConfig will create an incluster config by default. +// If serviceKubeConfig is set, it will use that instead. +func getServiceClusterConfig() (*rest.Config, error) { + + if s.serviceKubeConfig != "" { + kubeconfig, err := os.ReadFile(s.serviceKubeConfig) + if err != nil { + return nil, err + } + + clientConfig, err := clientcmd.NewClientConfigFromBytes(kubeconfig) + if err != nil { + return nil, err + } + + config, err := clientConfig.ClientConfig() + if err != nil { + return nil, err + } + return config, nil + } + + config, err := rest.InClusterConfig() + if err != nil { + return nil, err + } + + return config, nil } diff --git a/pkg/apiserver/appcat/appcat.go b/pkg/apiserver/appcat/appcat.go index 14a9bfbb86..3e9581235c 100644 --- a/pkg/apiserver/appcat/appcat.go +++ b/pkg/apiserver/appcat/appcat.go @@ -3,8 +3,8 @@ package appcat import ( crossplane "github.com/crossplane/crossplane/apis/apiextensions/v1" appcatv1 "github.com/vshn/appcat/v4/apis/apiserver/v1" - "github.com/vshn/appcat/v4/pkg/apiserver" "github.com/vshn/appcat/v4/pkg/apiserver/noop" + "github.com/vshn/appcat/v4/pkg/common/utils" "k8s.io/apimachinery/pkg/runtime" genericregistry "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" @@ -37,7 +37,7 @@ func New() restbuilder.ResourceHandlerProvider { noopImplementation := noop.New(s, &appcatv1.AppCat{}, &appcatv1.AppCatList{}) - if !apiserver.IsTypeAvailable(crossplane.SchemeGroupVersion.String(), "Composition") { + if !utils.IsKindAvailable(crossplane.SchemeGroupVersion, "Composition", loopback.GetLoopbackMasterClientConfig()) { return noopImplementation, nil } diff --git a/pkg/apiserver/common.go b/pkg/apiserver/common.go index 67e71aec35..fa4411a587 100644 --- a/pkg/apiserver/common.go +++ b/pkg/apiserver/common.go @@ -6,8 +6,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/discovery" - "sigs.k8s.io/apiserver-runtime/pkg/util/loopback" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime/schema" @@ -91,21 +89,3 @@ func GetBackupColumnDefinition() []metav1.TableColumnDefinition { {Name: "Age", Type: "date", Description: desc["creationTimestamp"]}, } } - -func IsTypeAvailable(gv string, kind string) bool { - d, err := discovery.NewDiscoveryClientForConfig(loopback.GetLoopbackMasterClientConfig()) - if err != nil { - return false - } - resources, err := d.ServerResourcesForGroupVersion(gv) - if err != nil { - return false - } - - for _, res := range resources.APIResources { - if res.Kind == kind { - return true - } - } - return false -} diff --git a/pkg/apiserver/vshn/mariadb/backup.go b/pkg/apiserver/vshn/mariadb/backup.go index 6f3429e81b..7282a52644 100644 --- a/pkg/apiserver/vshn/mariadb/backup.go +++ b/pkg/apiserver/vshn/mariadb/backup.go @@ -4,9 +4,9 @@ import ( k8upv1 "github.com/k8up-io/k8up/v2/api/v1" appcatv1 "github.com/vshn/appcat/v4/apis/apiserver/v1" vshnv1 "github.com/vshn/appcat/v4/apis/vshn/v1" - "github.com/vshn/appcat/v4/pkg/apiserver" "github.com/vshn/appcat/v4/pkg/apiserver/noop" "github.com/vshn/appcat/v4/pkg/apiserver/vshn/k8up" + "github.com/vshn/appcat/v4/pkg/common/utils" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" genericregistry "k8s.io/apiserver/pkg/registry/generic" @@ -37,7 +37,7 @@ func New() restbuilder.ResourceHandlerProvider { noopImplementation := noop.New(s, &appcatv1.VSHNMariaDBBackup{}, &appcatv1.VSHNMariaDBBackupList{}) - if !apiserver.IsTypeAvailable(vshnv1.GroupVersion.String(), "XVSHNMariaDB") { + if !utils.IsKindAvailable(vshnv1.GroupVersion, "XVSHNMariaDB", loopback.GetLoopbackMasterClientConfig()) { return noopImplementation, nil } diff --git a/pkg/apiserver/vshn/nextcloud/backup.go b/pkg/apiserver/vshn/nextcloud/backup.go index b21da96636..3762175d1c 100644 --- a/pkg/apiserver/vshn/nextcloud/backup.go +++ b/pkg/apiserver/vshn/nextcloud/backup.go @@ -4,10 +4,10 @@ import ( k8upv1 "github.com/k8up-io/k8up/v2/api/v1" appcatv1 "github.com/vshn/appcat/v4/apis/apiserver/v1" vshnv1 "github.com/vshn/appcat/v4/apis/vshn/v1" - "github.com/vshn/appcat/v4/pkg/apiserver" "github.com/vshn/appcat/v4/pkg/apiserver/noop" "github.com/vshn/appcat/v4/pkg/apiserver/vshn/k8up" "github.com/vshn/appcat/v4/pkg/apiserver/vshn/postgres" + "github.com/vshn/appcat/v4/pkg/common/utils" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" genericregistry "k8s.io/apiserver/pkg/registry/generic" @@ -41,7 +41,7 @@ func New() restbuilder.ResourceHandlerProvider { noopImplementation := noop.New(s, &appcatv1.VSHNNextcloudBackup{}, &appcatv1.VSHNNextcloudBackupList{}) - if !apiserver.IsTypeAvailable(vshnv1.GroupVersion.String(), "XVSHNNextcloud") { + if !utils.IsKindAvailable(vshnv1.GroupVersion, "XVSHNNextcloud", loopback.GetLoopbackMasterClientConfig()) { return noopImplementation, nil } diff --git a/pkg/apiserver/vshn/postgres/backup.go b/pkg/apiserver/vshn/postgres/backup.go index 90a2fb03a1..3d6a05fec9 100644 --- a/pkg/apiserver/vshn/postgres/backup.go +++ b/pkg/apiserver/vshn/postgres/backup.go @@ -3,8 +3,8 @@ package postgres import ( appcatv1 "github.com/vshn/appcat/v4/apis/apiserver/v1" vshnv1 "github.com/vshn/appcat/v4/apis/vshn/v1" - "github.com/vshn/appcat/v4/pkg/apiserver" "github.com/vshn/appcat/v4/pkg/apiserver/noop" + "github.com/vshn/appcat/v4/pkg/common/utils" "k8s.io/apimachinery/pkg/runtime" genericregistry "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" @@ -29,7 +29,7 @@ func New() restbuilder.ResourceHandlerProvider { noopImplementation := noop.New(s, &appcatv1.VSHNPostgresBackup{}, &appcatv1.VSHNPostgresBackupList{}) - if !apiserver.IsTypeAvailable(vshnv1.GroupVersion.String(), "VSHNPostgreSQL") { + if !utils.IsKindAvailable(vshnv1.GroupVersion, "VSHNPostgreSQL", loopback.GetLoopbackMasterClientConfig()) { return noopImplementation, nil } diff --git a/pkg/apiserver/vshn/redis/backup.go b/pkg/apiserver/vshn/redis/backup.go index 416c5b1614..42d9f2cb8a 100644 --- a/pkg/apiserver/vshn/redis/backup.go +++ b/pkg/apiserver/vshn/redis/backup.go @@ -4,9 +4,9 @@ import ( k8upv1 "github.com/k8up-io/k8up/v2/api/v1" appcatv1 "github.com/vshn/appcat/v4/apis/apiserver/v1" vshnv1 "github.com/vshn/appcat/v4/apis/vshn/v1" - "github.com/vshn/appcat/v4/pkg/apiserver" "github.com/vshn/appcat/v4/pkg/apiserver/noop" "github.com/vshn/appcat/v4/pkg/apiserver/vshn/k8up" + "github.com/vshn/appcat/v4/pkg/common/utils" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" genericregistry "k8s.io/apiserver/pkg/registry/generic" @@ -37,7 +37,7 @@ func New() restbuilder.ResourceHandlerProvider { noopImplementation := noop.New(s, &appcatv1.VSHNRedisBackup{}, &appcatv1.VSHNRedisBackupList{}) - if !apiserver.IsTypeAvailable(vshnv1.GroupVersion.String(), "XVSHNRedis") { + if !utils.IsKindAvailable(vshnv1.GroupVersion, "XVSHNRedis", loopback.GetLoopbackMasterClientConfig()) { return noopImplementation, nil } diff --git a/pkg/common/utils/kinds.go b/pkg/common/utils/kinds.go new file mode 100644 index 0000000000..c579ee90ee --- /dev/null +++ b/pkg/common/utils/kinds.go @@ -0,0 +1,26 @@ +package utils + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/discovery" + "k8s.io/client-go/rest" +) + +// IsKindAvailable will check if the given type is available +func IsKindAvailable(gv schema.GroupVersion, kind string, config *rest.Config) bool { + d, err := discovery.NewDiscoveryClientForConfig(config) + if err != nil { + return false + } + resources, err := d.ServerResourcesForGroupVersion(gv.String()) + if err != nil { + return false + } + + for _, res := range resources.APIResources { + if res.Kind == kind { + return true + } + } + return false +} diff --git a/pkg/comp-functions/functions/common/interfaces.go b/pkg/comp-functions/functions/common/interfaces.go index f4ff98b8ed..cb38c6eaf9 100644 --- a/pkg/comp-functions/functions/common/interfaces.go +++ b/pkg/comp-functions/functions/common/interfaces.go @@ -28,12 +28,17 @@ type InfoGetter interface { // InstanceNamespaceInfo provides all the necessary information to create // an instance namespace. type InstanceNamespaceInfo interface { + InstanceNamespaceGetter GetName() string GetClaimNamespace() string - GetInstanceNamespace() string GetLabels() map[string]string } +// InstanceNamespaceGetter returns the instance namespace of the given object +type InstanceNamespaceGetter interface { + GetInstanceNamespace() string +} + // Composite can get and set the relevant information on a given composite. type Composite interface { InfoGetter diff --git a/pkg/sliexporter/maintenance_controller/controller.go b/pkg/sliexporter/maintenance_controller/controller.go index f8ec714d0e..e4867273db 100644 --- a/pkg/sliexporter/maintenance_controller/controller.go +++ b/pkg/sliexporter/maintenance_controller/controller.go @@ -10,7 +10,10 @@ import ( apimeta "k8s.io/apimachinery/pkg/api/meta" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/cluster" + "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/source" ) //+kubebuilder:rbac:groups=managedupgrade.appuio.io,resources=upgradejobs,verbs=get;list;watch @@ -90,8 +93,19 @@ func (r *MaintenanceReconciler) jobState(job managedupgradev1beta1.UpgradeJob) s } // SetupWithManager sets up the controller with the Manager. -func (r *MaintenanceReconciler) SetupWithManager(mgr ctrl.Manager) error { +func (r *MaintenanceReconciler) SetupWithManager(mgr ctrl.Manager, serviceCluster *cluster.Cluster) error { + sc := *serviceCluster + + // For external reconcile triggers we can't register a kind via `For()` + // instead we have to name the reconciler something + // usually the name is the lowercase of the kind + // so that's what I've used here. return ctrl.NewControllerManagedBy(mgr). - For(&managedupgradev1beta1.UpgradeJob{}). + Named("upgradejob"). + // This is the magic sauce, it makes the reconciler reconcile on events happening on the serviceCluster + WatchesRawSource(source.Kind( + sc.GetCache(), + &managedupgradev1beta1.UpgradeJob{}, + &handler.TypedEnqueueRequestForObject[*managedupgradev1beta1.UpgradeJob]{})). Complete(r) } diff --git a/pkg/sliexporter/sli_reconciler/reconciler.go b/pkg/sliexporter/sli_reconciler/reconciler.go index d8667394c3..5a591baebd 100644 --- a/pkg/sliexporter/sli_reconciler/reconciler.go +++ b/pkg/sliexporter/sli_reconciler/reconciler.go @@ -6,7 +6,10 @@ import ( "time" "github.com/go-logr/logr" + "github.com/vshn/appcat/v4/pkg/comp-functions/functions/common" "github.com/vshn/appcat/v4/pkg/sliexporter/probes" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" @@ -32,11 +35,14 @@ type Reconciler struct { startupGracePeriod time.Duration fetchProberFor func(context.Context, Service) (probes.Prober, error) client client.Client + scClient client.Client } // New returns a new Reconciler func New(inst Service, l logr.Logger, pm ProbeManager, serviceKey string, nn types.NamespacedName, - client client.Client, startupGracePeriod time.Duration, fetchProberFor func(context.Context, Service) (probes.Prober, error)) *Reconciler { + client client.Client, startupGracePeriod time.Duration, + fetchProberFor func(context.Context, Service) (probes.Prober, error), + scClient client.Client) *Reconciler { return &Reconciler{ inst: inst, l: l, @@ -46,6 +52,7 @@ func New(inst Service, l logr.Logger, pm ProbeManager, serviceKey string, nn typ client: client, startupGracePeriod: startupGracePeriod, fetchProberFor: fetchProberFor, + scClient: scClient, } } @@ -84,6 +91,15 @@ func (r *Reconciler) Reconcile(ctx context.Context) (ctrl.Result, error) { return res, nil } + namespaceExists, err := r.namespaceExists(ctx) + if err != nil { + return ctrl.Result{}, err + } + + if !namespaceExists { + return ctrl.Result{}, nil + } + probe, err := r.fetchProberFor(ctx, r.inst) // By using the composite the credential secret is available instantly, but initially empty. if err != nil && (apierrors.IsNotFound(err) || err == errNotReady) { @@ -105,3 +121,25 @@ func (r *Reconciler) Reconcile(ctx context.Context) (ctrl.Result, error) { r.pm.StartProbe(probe) return res, nil } + +// namespaceExists detects wether or not the namespace exists in the service +// cluster. If it doesn't exist then we skip the reconcilation for this instance. +func (r Reconciler) namespaceExists(ctx context.Context) (bool, error) { + comp, ok := r.inst.(common.InstanceNamespaceGetter) + if !ok { + return false, fmt.Errorf("resource does not implement common.InstanceNamespaceGetter") + } + + ns := &corev1.Namespace{} + + err := r.scClient.Get(ctx, types.NamespacedName{Name: comp.GetInstanceNamespace()}, ns) + if err != nil { + if errors.IsNotFound(err) { + r.l.Info("instance doesn't have a instance namespace on this cluster, skipping") + return false, nil + } + return false, err + } + + return true, nil +} diff --git a/pkg/sliexporter/vshnkeycloak_controller/vshnkeycloak_controller.go b/pkg/sliexporter/vshnkeycloak_controller/vshnkeycloak_controller.go index e617a1c5cd..b45c046014 100644 --- a/pkg/sliexporter/vshnkeycloak_controller/vshnkeycloak_controller.go +++ b/pkg/sliexporter/vshnkeycloak_controller/vshnkeycloak_controller.go @@ -32,6 +32,7 @@ type VSHNKeycloakReconciler struct { ProbeManager probeManager StartupGracePeriod time.Duration + ScClient client.Client } type probeManager interface { @@ -52,7 +53,7 @@ func (r *VSHNKeycloakReconciler) Reconcile(ctx context.Context, req ctrl.Request inst := &vshnv1.XVSHNKeycloak{} - reconciler := slireconciler.New(inst, l, r.ProbeManager, vshnKeycloakServiceKey, req.NamespacedName, r.Client, r.StartupGracePeriod, r.getKeycloakProber) + reconciler := slireconciler.New(inst, l, r.ProbeManager, vshnKeycloakServiceKey, req.NamespacedName, r.Client, r.StartupGracePeriod, r.getKeycloakProber, r.ScClient) return reconciler.Reconcile(ctx) diff --git a/pkg/sliexporter/vshnkeycloak_controller/vshnkeycloak_controller_test.go b/pkg/sliexporter/vshnkeycloak_controller/vshnkeycloak_controller_test.go index 115cf95f86..b810224046 100644 --- a/pkg/sliexporter/vshnkeycloak_controller/vshnkeycloak_controller_test.go +++ b/pkg/sliexporter/vshnkeycloak_controller/vshnkeycloak_controller_test.go @@ -50,10 +50,10 @@ func getFakeKey(pi probes.ProbeInfo) key { } func TestVSHNKeycloakReconciler_Reconcile(t *testing.T) { - keycloak := newTestVSHNKeycloak("bar", "foo", "cred") + keycloak, ns := newTestVSHNKeycloak("bar", "foo", "cred") r, manager, client := setupVSHNKeycloakTest(t, - keycloak, + keycloak, ns, newTestVSHNKeycloakCred("bar", "cred")) req := ctrl.Request{ @@ -92,13 +92,14 @@ func setupVSHNKeycloakTest(t *testing.T, objs ...client.Object) (VSHNKeycloakRec Scheme: scheme, StartupGracePeriod: 5 * time.Minute, ProbeManager: manager, + ScClient: client, } return r, manager, client } -func newTestVSHNKeycloak(namespace, name, cred string) *vshnv1.XVSHNKeycloak { - return &vshnv1.XVSHNKeycloak{ +func newTestVSHNKeycloak(namespace, name, cred string) (*vshnv1.XVSHNKeycloak, *corev1.Namespace) { + claim := &vshnv1.XVSHNKeycloak{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: namespace, @@ -113,6 +114,14 @@ func newTestVSHNKeycloak(namespace, name, cred string) *vshnv1.XVSHNKeycloak { }, }, } + + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: claim.GetInstanceNamespace(), + }, + } + + return claim, ns } func newTestVSHNKeycloakCred(namespace, name string) *corev1.Secret { diff --git a/pkg/sliexporter/vshnmariadb_controller/vshnmariadb_controller.go b/pkg/sliexporter/vshnmariadb_controller/vshnmariadb_controller.go index 9deaef6b48..8814960907 100644 --- a/pkg/sliexporter/vshnmariadb_controller/vshnmariadb_controller.go +++ b/pkg/sliexporter/vshnmariadb_controller/vshnmariadb_controller.go @@ -37,6 +37,7 @@ type VSHNMariaDBReconciler struct { ProbeManager probeManager StartupGracePeriod time.Duration MariaDBDialer func(service, name, namespace, dsn, organization, serviceLevel, caCRT string, ha, TLSEnabled bool) (*probes.MariaDB, error) + ScClient client.Client } //+kubebuilder:rbac:groups=vshn.appcat.vshn.io,resources=xvshnmariadbs,verbs=get;list;watch @@ -54,7 +55,7 @@ func (r *VSHNMariaDBReconciler) Reconcile(ctx context.Context, req ctrl.Request) inst := &vshnv1.XVSHNMariaDB{} - reconciler := slireconciler.New(inst, l, r.ProbeManager, vshnMariadbServiceKey, req.NamespacedName, r.Client, r.StartupGracePeriod, r.fetchProberFor) + reconciler := slireconciler.New(inst, l, r.ProbeManager, vshnMariadbServiceKey, req.NamespacedName, r.Client, r.StartupGracePeriod, r.fetchProberFor, r.ScClient) return reconciler.Reconcile(ctx) } diff --git a/pkg/sliexporter/vshnmariadb_controller/vshnmariadb_controller_test.go b/pkg/sliexporter/vshnmariadb_controller/vshnmariadb_controller_test.go index 81d87ce2d5..d38865089d 100644 --- a/pkg/sliexporter/vshnmariadb_controller/vshnmariadb_controller_test.go +++ b/pkg/sliexporter/vshnmariadb_controller/vshnmariadb_controller_test.go @@ -52,10 +52,10 @@ func getFakeKey(pi probes.ProbeInfo) key { } func TestVSHNMariaDB_Reconcile(t *testing.T) { - mariadb := newTestVSHNMariaDB("bar", "foo", "cred") + mariadb, ns := newTestVSHNMariaDB("bar", "foo", "cred") r, manager, client := setupVSHNMariaDBTest(t, - mariadb, + mariadb, ns, newTestVSHNMariaDBCred("bar", "cred")) req := ctrl.Request{ @@ -94,13 +94,14 @@ func setupVSHNMariaDBTest(t *testing.T, objs ...client.Object) (VSHNMariaDBRecon Scheme: scheme, StartupGracePeriod: 5 * time.Minute, ProbeManager: manager, + ScClient: client, } return r, manager, client } -func newTestVSHNMariaDB(namespace, name, cred string) *vshnv1.XVSHNMariaDB { - return &vshnv1.XVSHNMariaDB{ +func newTestVSHNMariaDB(namespace, name, cred string) (*vshnv1.XVSHNMariaDB, *corev1.Namespace) { + claim := &vshnv1.XVSHNMariaDB{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: namespace, @@ -115,6 +116,14 @@ func newTestVSHNMariaDB(namespace, name, cred string) *vshnv1.XVSHNMariaDB { }, }, } + + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: claim.GetInstanceNamespace(), + }, + } + + return claim, ns } func newTestVSHNMariaDBCred(namespace, name string) *corev1.Secret { diff --git a/pkg/sliexporter/vshnminio_controller/vshnminio_controller.go b/pkg/sliexporter/vshnminio_controller/vshnminio_controller.go index 3ffac70f55..df0636ed2b 100644 --- a/pkg/sliexporter/vshnminio_controller/vshnminio_controller.go +++ b/pkg/sliexporter/vshnminio_controller/vshnminio_controller.go @@ -34,6 +34,7 @@ type VSHNMinioReconciler struct { ProbeManager probeManager StartupGracePeriod time.Duration MinioDialer func(service, name, namespace, organization, sla, endpointURL string, ha bool, opts minio.Options) (*probes.VSHNMinio, error) + ScClient client.Client } type probeManager interface { @@ -54,7 +55,7 @@ func (r *VSHNMinioReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( inst := &vshnv1.XVSHNMinio{} - reconciler := slireconciler.New(inst, l, r.ProbeManager, vshnMinioServiceKey, req.NamespacedName, r.Client, r.StartupGracePeriod, r.getMinioProber) + reconciler := slireconciler.New(inst, l, r.ProbeManager, vshnMinioServiceKey, req.NamespacedName, r.Client, r.StartupGracePeriod, r.getMinioProber, r.ScClient) return reconciler.Reconcile(ctx) diff --git a/pkg/sliexporter/vshnminio_controller/vshnminio_controller_test.go b/pkg/sliexporter/vshnminio_controller/vshnminio_controller_test.go index 19e32585c7..61f6a4e036 100644 --- a/pkg/sliexporter/vshnminio_controller/vshnminio_controller_test.go +++ b/pkg/sliexporter/vshnminio_controller/vshnminio_controller_test.go @@ -55,13 +55,13 @@ func getFakeKey(pi probes.ProbeInfo) key { } func TestReconciler(t *testing.T) { - minio := giveMeMinio(bucketName, namespace) + minio, ns := giveMeMinio(bucketName, namespace) ct := metav1.Now().Add(-20 * time.Minute) minio.CreationTimestamp = metav1.Time{Time: ct} r, manager, client := setupVSHNMinioTest(t, - minio, + minio, ns, newTestVSHNMinioCred(bucketName, namespace), ) @@ -90,10 +90,10 @@ func TestReconciler(t *testing.T) { } func TestVSHNMinio_Startup_NoCreds_Dont_Probe(t *testing.T) { - minio := giveMeMinio(bucketName, namespace) + minio, ns := giveMeMinio(bucketName, namespace) r, manager, _ := setupVSHNMinioTest(t, - minio, + minio, ns, ) req := ctrl.Request{ @@ -117,10 +117,10 @@ func TestVSHNMinio_Startup_NoCreds_Dont_Probe(t *testing.T) { } func TestVSHNMinio_NoRef_Dont_Probe(t *testing.T) { - db := giveMeMinio("bar", "foo") + db, ns := giveMeMinio("bar", "foo") db.Spec.WriteConnectionSecretToReference.Name = "" r, manager, _ := setupVSHNMinioTest(t, - db, + db, ns, ) req := ctrl.Request{ @@ -140,8 +140,8 @@ func TestVSHNMinio_NoRef_Dont_Probe(t *testing.T) { assert.False(t, manager.probers[getFakeKey(pi)]) } -func giveMeMinio(bucketName string, namespace string) *vshnv1.XVSHNMinio { - return &vshnv1.XVSHNMinio{ +func giveMeMinio(bucketName string, namespace string) (*vshnv1.XVSHNMinio, *corev1.Namespace) { + claim := &vshnv1.XVSHNMinio{ TypeMeta: metav1.TypeMeta{ Kind: "XVSHNMinio", APIVersion: "vshn.appcat.vshn.io/v1", @@ -163,6 +163,14 @@ func giveMeMinio(bucketName string, namespace string) *vshnv1.XVSHNMinio { }, }, } + + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: claim.GetInstanceNamespace(), + }, + } + + return claim, ns } func setupVSHNMinioTest(t *testing.T, objs ...client.Object) (VSHNMinioReconciler, *fakeProbeManager, client.Client) { @@ -181,6 +189,7 @@ func setupVSHNMinioTest(t *testing.T, objs ...client.Object) (VSHNMinioReconcile ProbeManager: manager, StartupGracePeriod: 5 * time.Minute, MinioDialer: fakeMinioDialer, + ScClient: client, } return r, manager, client diff --git a/pkg/sliexporter/vshnpostgresql_controller/vshnpostgresql_controller.go b/pkg/sliexporter/vshnpostgresql_controller/vshnpostgresql_controller.go index 219db276cb..7ac988f766 100644 --- a/pkg/sliexporter/vshnpostgresql_controller/vshnpostgresql_controller.go +++ b/pkg/sliexporter/vshnpostgresql_controller/vshnpostgresql_controller.go @@ -50,6 +50,7 @@ type VSHNPostgreSQLReconciler struct { ProbeManager probeManager StartupGracePeriod time.Duration PostgreDialer func(service, name, namespace, dsn, organization, serviceLevel string, ha bool, ops ...func(*pgxpool.Config) error) (*probes.PostgreSQL, error) + ScClient client.Client } type probeManager interface { @@ -71,7 +72,7 @@ func (r *VSHNPostgreSQLReconciler) Reconcile(ctx context.Context, req ctrl.Reque inst := &vshnv1.XVSHNPostgreSQL{} - reconciler := slireconciler.New(inst, l, r.ProbeManager, vshnpostgresqlsServiceKey, req.NamespacedName, r.Client, r.StartupGracePeriod, r.fetchProberFor) + reconciler := slireconciler.New(inst, l, r.ProbeManager, vshnpostgresqlsServiceKey, req.NamespacedName, r.Client, r.StartupGracePeriod, r.fetchProberFor, r.ScClient) return reconciler.Reconcile(ctx) } diff --git a/pkg/sliexporter/vshnpostgresql_controller/vshnpostgresql_controller_test.go b/pkg/sliexporter/vshnpostgresql_controller/vshnpostgresql_controller_test.go index 814d4195ff..bd0b36eb30 100644 --- a/pkg/sliexporter/vshnpostgresql_controller/vshnpostgresql_controller_test.go +++ b/pkg/sliexporter/vshnpostgresql_controller/vshnpostgresql_controller_test.go @@ -26,9 +26,9 @@ import ( ) func TestVSHNPostgreSQL_StartStop(t *testing.T) { - db := newTestVSHNPostgres("bar", "foo", "creds", 1) + db, ns := newTestVSHNPostgres("bar", "foo", "creds", 1) r, manager, client := setupVSHNPostgreTest(t, - db, + db, ns, newTestVSHNPostgresCred("bar", "creds"), ) @@ -54,10 +54,10 @@ func TestVSHNPostgreSQL_StartStop(t *testing.T) { } func TestVSHNPostgreSQL_StartStop_WithFinalizer(t *testing.T) { - db := newTestVSHNPostgres("bar", "foo", "creds", 1) + db, ns := newTestVSHNPostgres("bar", "foo", "creds", 1) db.SetFinalizers([]string{"foobar.vshn.io"}) r, manager, client := setupVSHNPostgreTest(t, - db, + db, ns, newTestVSHNPostgresCred("bar", "creds"), ) @@ -83,15 +83,15 @@ func TestVSHNPostgreSQL_StartStop_WithFinalizer(t *testing.T) { } func TestVSHNPostgreSQL_Multi(t *testing.T) { - dbBar := newTestVSHNPostgres("bar", "foo", "creds", 1) - dbBarer := newTestVSHNPostgres("bar", "fooer", "credentials", 1) - dbBuzz := newTestVSHNPostgres("buzz", "foobar", "creds", 1) + dbBar, nsBar := newTestVSHNPostgres("bar", "foo", "creds", 1) + dbBarer, nsBarer := newTestVSHNPostgres("bar", "fooer", "credentials", 1) + dbBuzz, nsBuzz := newTestVSHNPostgres("buzz", "foobar", "creds", 1) r, manager, c := setupVSHNPostgreTest(t, - dbBar, + dbBar, nsBar, newTestVSHNPostgresCred("bar", "creds"), - dbBarer, + dbBarer, nsBarer, newTestVSHNPostgresCred("bar", "credentials"), - dbBuzz, + dbBuzz, nsBuzz, newTestVSHNPostgresCred("buzz", "creds"), ) @@ -129,11 +129,11 @@ func TestVSHNPostgreSQL_Multi(t *testing.T) { } func TestVSHNPostgreSQL_Startup_NoCreds_Dont_Probe(t *testing.T) { - db := newTestVSHNPostgres("bar", "foo", "creds", 1) + db, ns := newTestVSHNPostgres("bar", "foo", "creds", 1) cd := metav1.Now().Add(time.Minute * -6) db.SetCreationTimestamp(metav1.Time{Time: cd}) r, manager, _ := setupVSHNPostgreTest(t, - db, + db, ns, ) pi := probes.ProbeInfo{ Service: "VSHNPostgreSQL", @@ -151,10 +151,10 @@ func TestVSHNPostgreSQL_Startup_NoCreds_Dont_Probe(t *testing.T) { } func TestVSHNPostgreSQL_NoRef_Dont_Probe(t *testing.T) { - db := newTestVSHNPostgres("bar", "foo", "creds", 1) + db, ns := newTestVSHNPostgres("bar", "foo", "creds", 1) db.Spec.WriteConnectionSecretToReference.Name = "" r, manager, _ := setupVSHNPostgreTest(t, - db, + db, ns, ) pi := probes.ProbeInfo{ Service: "VSHNPostgreSQL", @@ -168,10 +168,10 @@ func TestVSHNPostgreSQL_NoRef_Dont_Probe(t *testing.T) { } func TestVSHNPostgreSQL_Started_NoCreds_Probe_Failure(t *testing.T) { - db := newTestVSHNPostgres("bar", "foo", "creds", 1) + db, ns := newTestVSHNPostgres("bar", "foo", "creds", 1) db.SetCreationTimestamp(metav1.Time{Time: time.Now().Add(-1 * time.Hour)}) r, manager, _ := setupVSHNPostgreTest(t, - db, + db, ns, ) pi := probes.ProbeInfo{ Service: "VSHNPostgreSQL", @@ -186,7 +186,7 @@ func TestVSHNPostgreSQL_Started_NoCreds_Probe_Failure(t *testing.T) { } func TestVSHNPostgreSQL_PassCredentials(t *testing.T) { - db := newTestVSHNPostgres("bar", "foo", "creds", 3) + db, ns := newTestVSHNPostgres("bar", "foo", "creds", 3) cred := newTestVSHNPostgresCred("bar", "creds") cred.Data = map[string][]byte{ "POSTGRESQL_USER": []byte("userfoo"), @@ -197,7 +197,7 @@ func TestVSHNPostgreSQL_PassCredentials(t *testing.T) { "ca.crt": []byte("-----BEGIN CERTIFICATE-----MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzELMAkG..."), } r, manager, client := setupVSHNPostgreTest(t, - db, + db, ns, cred, &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ @@ -298,13 +298,14 @@ func setupVSHNPostgreTest(t *testing.T, objs ...client.Object) (VSHNPostgreSQLRe ProbeManager: manager, StartupGracePeriod: 5 * time.Minute, PostgreDialer: fakePostgreDialer, + ScClient: client, } return r, manager, client } -func newTestVSHNPostgres(namespace, name, cred string, instances int) *vshnv1.XVSHNPostgreSQL { - return &vshnv1.XVSHNPostgreSQL{ +func newTestVSHNPostgres(namespace, name, cred string, instances int) (*vshnv1.XVSHNPostgreSQL, *corev1.Namespace) { + claim := &vshnv1.XVSHNPostgreSQL{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: namespace, @@ -320,6 +321,14 @@ func newTestVSHNPostgres(namespace, name, cred string, instances int) *vshnv1.XV }, }, } + + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: claim.GetInstanceNamespace(), + }, + } + + return claim, ns } func newTestVSHNPostgresCred(namespace, name string) *corev1.Secret { return &corev1.Secret{ diff --git a/pkg/sliexporter/vshnredis_controller/vshnredis_controller.go b/pkg/sliexporter/vshnredis_controller/vshnredis_controller.go index d6fe32b1f4..18880733b4 100644 --- a/pkg/sliexporter/vshnredis_controller/vshnredis_controller.go +++ b/pkg/sliexporter/vshnredis_controller/vshnredis_controller.go @@ -35,6 +35,7 @@ type VSHNRedisReconciler struct { ProbeManager probeManager StartupGracePeriod time.Duration RedisDialer func(service, name, namespace, organization, sla string, ha bool, opts redis.Options) (*probes.VSHNRedis, error) + ScClient client.Client } type probeManager interface { @@ -54,7 +55,7 @@ func (r *VSHNRedisReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( l.Info("Reconciling VSHNRedis") inst := &vshnv1.XVSHNRedis{} - reconciler := slireconciler.New(inst, l, r.ProbeManager, vshnRedisServiceKey, req.NamespacedName, r.Client, r.StartupGracePeriod, r.getRedisProber) + reconciler := slireconciler.New(inst, l, r.ProbeManager, vshnRedisServiceKey, req.NamespacedName, r.Client, r.StartupGracePeriod, r.getRedisProber, r.ScClient) return reconciler.Reconcile(ctx) diff --git a/pkg/sliexporter/vshnredis_controller/vshnredis_controller_test.go b/pkg/sliexporter/vshnredis_controller/vshnredis_controller_test.go index ce022a6be4..1e8a9ca2f8 100644 --- a/pkg/sliexporter/vshnredis_controller/vshnredis_controller_test.go +++ b/pkg/sliexporter/vshnredis_controller/vshnredis_controller_test.go @@ -153,9 +153,9 @@ nrfsBwoJpAcOmKDb/zOwtqOiSeZ4ef4DULUpz61vNmKch4N2fDDdcjuHCXo0tA== `) func TestVSHNRedis_StartStop(t *testing.T) { - ns, db, claim := newTestVSHNRedis("bar", "foo", "creds", true) - r, manager, client := setupVSHNRedisTest(t, - ns, db, claim, + ns, db, claim, instns := newTestVSHNRedis("bar", "foo", "creds", true) + r, manager, client := setupVSHNRedisTest(t, claim, + ns, db, instns, newTestVSHNRedisCred("bar", "creds"), ) @@ -182,10 +182,10 @@ func TestVSHNRedis_StartStop(t *testing.T) { } func TestVSHNRedis_StartStop_WithFinalizer(t *testing.T) { - ns, db, claim := newTestVSHNRedis("bar", "foo", "creds", true) + ns, db, claim, instns := newTestVSHNRedis("bar", "foo", "creds", true) db.SetFinalizers([]string{"foobar.vshn.io"}) - r, manager, client := setupVSHNRedisTest(t, - ns, db, claim, + r, manager, client := setupVSHNRedisTest(t, claim, + ns, db, instns, newTestVSHNRedisCred("bar", "creds"), ) @@ -211,15 +211,15 @@ func TestVSHNRedis_StartStop_WithFinalizer(t *testing.T) { } func TestVSHNRedis_Multi(t *testing.T) { - nsBar, dbBar, claimBar := newTestVSHNRedis("bar", "foo", "creds", true) - nsBarer, dbBarer, claimBarer := newTestVSHNRedis("barer", "fooer", "credentials", true) - nsBuzz, dbBuzz, claimBuzz := newTestVSHNRedis("buzz", "fooz", "creds", true) - r, manager, c := setupVSHNRedisTest(t, - nsBar, dbBar, claimBar, + nsBar, dbBar, claimBar, instnsBar := newTestVSHNRedis("bar", "foo", "creds", true) + nsBarer, dbBarer, claimBarer, instnsBarer := newTestVSHNRedis("barer", "fooer", "credentials", true) + nsBuzz, dbBuzz, claimBuzz, instnsBuzz := newTestVSHNRedis("buzz", "fooz", "creds", true) + r, manager, c := setupVSHNRedisTest(t, claimBar, + nsBar, dbBar, instnsBar, newTestVSHNRedisCred("bar", "creds"), - nsBarer, dbBarer, claimBarer, + nsBarer, dbBarer, claimBarer, instnsBarer, newTestVSHNRedisCred("barer", "credentials"), - nsBuzz, dbBuzz, claimBuzz, + nsBuzz, dbBuzz, claimBuzz, instnsBuzz, newTestVSHNRedisCred("buzz", "creds"), ) @@ -260,10 +260,10 @@ func TestVSHNRedis_Multi(t *testing.T) { } func TestVSHNRedis_Startup_NoCreds_Dont_Probe(t *testing.T) { - ns, db, claim := newTestVSHNRedis("bar", "foo", "creds", true) + ns, db, claim, instns := newTestVSHNRedis("bar", "foo", "creds", true) db.SetCreationTimestamp(metav1.Now()) - r, manager, _ := setupVSHNRedisTest(t, - ns, db, claim, + r, manager, _ := setupVSHNRedisTest(t, claim, + ns, db, instns, ) pi := probes.ProbeInfo{ Service: "VSHNRedis", @@ -279,10 +279,10 @@ func TestVSHNRedis_Startup_NoCreds_Dont_Probe(t *testing.T) { } func TestVSHNRedis_NoRef_Dont_Probe(t *testing.T) { - ns, db, claim := newTestVSHNRedis("bar", "foo", "creds", true) + ns, db, claim, instns := newTestVSHNRedis("bar", "foo", "creds", true) db.Spec.WriteConnectionSecretToReference.Name = "" r, manager, _ := setupVSHNRedisTest(t, - ns, db, claim, + ns, db, claim, instns, ) pi := probes.ProbeInfo{ Service: "VSHNRedis", @@ -296,10 +296,10 @@ func TestVSHNRedis_NoRef_Dont_Probe(t *testing.T) { } func TestVSHNRedis_Started_NoCreds_Probe_Failure(t *testing.T) { - ns, db, claim := newTestVSHNRedis("bar", "foo", "creds", true) + ns, db, claim, instns := newTestVSHNRedis("bar", "foo", "creds", true) db.SetCreationTimestamp(metav1.Time{Time: time.Now().Add(-1 * time.Hour)}) - r, manager, _ := setupVSHNRedisTest(t, - ns, db, claim, + r, manager, _ := setupVSHNRedisTest(t, claim, + ns, db, instns, ) pi := probes.ProbeInfo{ Service: "VSHNRedis", @@ -315,7 +315,7 @@ func TestVSHNRedis_Started_NoCreds_Probe_Failure(t *testing.T) { } func TestVSHNRedis_PassCerdentials(t *testing.T) { - ns, db, claim := newTestVSHNRedis("bar", "foo", "creds", true) + ns, db, claim, instns := newTestVSHNRedis("bar", "foo", "creds", true) cred := newTestVSHNRedisCred("bar", "creds") cred.Data = map[string][]byte{ "REDIS_USER": []byte("userfoo"), @@ -327,8 +327,8 @@ func TestVSHNRedis_PassCerdentials(t *testing.T) { "tls.key": tls_key, "tls.crt": tls_crt, } - r, manager, client := setupVSHNRedisTest(t, - ns, db, claim, + r, manager, client := setupVSHNRedisTest(t, claim, + ns, db, instns, cred, ) r.RedisDialer = func(service, name, namespace, organization, sla string, ha bool, opts redis.Options) (*probes.VSHNRedis, error) { @@ -376,7 +376,7 @@ func TestVSHNRedis_PassCerdentials(t *testing.T) { } func TestVSHNRedis_Tls(t *testing.T) { - ns, db, claim := newTestVSHNRedis("bar", "foo", "creds", true) + ns, db, claim, instns := newTestVSHNRedis("bar", "foo", "creds", true) cred := newTestVSHNRedisCred("bar", "creds") cred.Data = map[string][]byte{ "REDIS_USER": []byte("userfoo"), @@ -388,8 +388,8 @@ func TestVSHNRedis_Tls(t *testing.T) { "tls.key": tls_key, "tls.crt": tls_crt, } - r, manager, client := setupVSHNRedisTest(t, - ns, db, claim, + r, manager, client := setupVSHNRedisTest(t, claim, + ns, db, instns, cred, ) r.RedisDialer = func(service, name, namespace, organization, sla string, ha bool, opts redis.Options) (*probes.VSHNRedis, error) { @@ -434,7 +434,7 @@ func TestVSHNRedis_Tls(t *testing.T) { } func TestVSHNRedis_NoTls(t *testing.T) { - ns, db, claim := newTestVSHNRedis("bar", "foo", "creds", false) + ns, db, claim, instns := newTestVSHNRedis("bar", "foo", "creds", false) cred := newTestVSHNRedisCred("bar", "creds") cred.Data = map[string][]byte{ "REDIS_USER": []byte("userfoo"), @@ -446,8 +446,8 @@ func TestVSHNRedis_NoTls(t *testing.T) { "tls.key": tls_key, "tls.crt": tls_crt, } - r, manager, client := setupVSHNRedisTest(t, - ns, db, claim, + r, manager, client := setupVSHNRedisTest(t, claim, + ns, db, instns, cred, ) r.RedisDialer = func(service, name, namespace, organization, sla string, ha bool, opts redis.Options) (*probes.VSHNRedis, error) { @@ -536,12 +536,13 @@ func setupVSHNRedisTest(t *testing.T, objs ...client.Object) (VSHNRedisReconcile ProbeManager: manager, StartupGracePeriod: 5 * time.Minute, RedisDialer: fakeRedisDialer, + ScClient: client, } return r, manager, client } -func newTestVSHNRedis(namespace, name, cred string, tlsEnabled bool) (*corev1.Namespace, *vshnv1.XVSHNRedis, *vshnv1.VSHNRedis) { +func newTestVSHNRedis(namespace, name, cred string, tlsEnabled bool) (*corev1.Namespace, *vshnv1.XVSHNRedis, *vshnv1.VSHNRedis, *corev1.Namespace) { ns := &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: namespace, @@ -590,7 +591,14 @@ func newTestVSHNRedis(namespace, name, cred string, tlsEnabled bool) (*corev1.Na }, }, } - return ns, db, claim + + instns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: claim.GetInstanceNamespace(), + }, + } + + return ns, db, claim, instns } func newTestVSHNRedisCred(namespace, name string) *corev1.Secret { return &corev1.Secret{