Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Available CRDs check feature #253

Merged
merged 2 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ WORKDIR /
COPY --from=builder /workspace/bin/manager .
COPY --from=builder /workspace/bin/status-reporter .
COPY --from=builder /workspace/bin/deployment-guard .
COPY --from=builder /workspace/hack/entrypoint.sh entrypoint
USER 65532:65532

ENTRYPOINT ["/manager"]
ENTRYPOINT ["/entrypoint"]
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ metadata:
categories: Storage
console.openshift.io/plugins: '["odf-client-console"]'
containerImage: quay.io/ocs-dev/ocs-client-operator:latest
createdAt: "2024-09-24T09:48:54Z"
createdAt: "2024-10-07T10:43:06Z"
description: OpenShift Data Foundation client operator enables consumption of
storage services from a remote centralized OpenShift Data Foundation provider
cluster.
Expand Down Expand Up @@ -774,7 +774,7 @@ spec:
- --leader-elect
- --console-port=9001
command:
- /manager
- /entrypoint
env:
- name: OPERATOR_NAMESPACE
valueFrom:
Expand Down
41 changes: 36 additions & 5 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ limitations under the License.
package main

import (
"context"
"flag"
"fmt"
"os"

apiv1alpha1 "github.com/red-hat-storage/ocs-client-operator/api/v1alpha1"
Expand All @@ -37,9 +39,11 @@ import (
secv1 "github.com/openshift/api/security/v1"
opv1a1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
ramenv1alpha1 "github.com/ramendr/ramen/api/v1alpha1"
admrv1 "k8s.io/api/admissionregistration/v1"
appsv1 "k8s.io/api/apps/v1"
extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
Expand Down Expand Up @@ -75,6 +79,7 @@ func init() {
utilruntime.Must(quotav1.AddToScheme(scheme))
utilruntime.Must(csiopv1a1.AddToScheme(scheme))
utilruntime.Must(nbapis.AddToScheme(scheme))
utilruntime.Must(ramenv1alpha1.AddToScheme(scheme))
//+kubebuilder:scaffold:scheme
}

Expand Down Expand Up @@ -129,11 +134,6 @@ func main() {
os.Exit(1)
}

if err != nil {
setupLog.Error(err, "Unable to get Client")
os.Exit(1)
}

// set namespace
err = utils.ValidateOperatorNamespace()
if err != nil {
Expand All @@ -147,6 +147,22 @@ func main() {
os.Exit(1)
}

// apiclient.New() returns a client without cache. cache is not initialized before mgr.Start()
// we need this because we need to watch for CRDs the operator is dependent on
apiClient, err := client.New(mgr.GetConfig(), client.Options{
Scheme: mgr.GetScheme(),
})
if err != nil {
setupLog.Error(err, "Unable to get Client")
os.Exit(1)
}

availCrds, err := getAvailableCRDNames(context.Background(), apiClient)
if err != nil {
setupLog.Error(err, "Unable get a list of available CRD names")
os.Exit(1)
}

setupLog.Info("setting up webhook server")
hookServer := mgr.GetWebhookServer()

Expand All @@ -172,6 +188,7 @@ func main() {
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
OperatorNamespace: utils.GetOperatorNamespace(),
AvailableCrds: availCrds,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "StorageClaim")
os.Exit(1)
Expand Down Expand Up @@ -202,3 +219,17 @@ func main() {
os.Exit(1)
}
}

func getAvailableCRDNames(ctx context.Context, cl client.Client) (map[string]bool, error) {
crdExist := map[string]bool{}
crdList := &metav1.PartialObjectMetadataList{}
crdList.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinitionList"))
if err := cl.List(ctx, crdList); err != nil {
return nil, fmt.Errorf("error listing CRDs, %v", err)
}
// Iterate over the list and populate the map
for i := range crdList.Items {
crdExist[crdList.Items[i].Name] = true
}
return crdExist, nil
}
2 changes: 1 addition & 1 deletion config/manager/manager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ spec:
fieldPath: metadata.namespace
containers:
- command:
- /manager
- /entrypoint
args:
- --leader-elect
image: controller:latest
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ require (
github.com/operator-framework/api v0.27.0
github.com/pkg/errors v0.9.1
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.76.0
github.com/ramendr/ramen/api v0.0.0-20241001141243-29d6f22ad237
github.com/red-hat-storage/ocs-client-operator/api v0.0.0-00010101000000-000000000000
github.com/red-hat-storage/ocs-operator/services/provider/api/v4 v4.0.0-20240917115204-741b9d6f263d
github.com/stretchr/testify v1.9.0
Expand All @@ -48,6 +49,7 @@ require (
github.com/openshift/custom-resource-status v1.1.3-0.20220503160415-f2fdb4999d87 // indirect
github.com/x448/float16 v0.8.4 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
k8s.io/component-base v0.31.0 // indirect
sigs.k8s.io/container-object-storage-interface-api v0.1.0 // indirect
)

Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,8 @@ github.com/prometheus/common v0.57.0 h1:Ro/rKjwdq9mZn1K5QPctzh+MA4Lp0BuYk5ZZEVho
github.com/prometheus/common v0.57.0/go.mod h1:7uRPFSUTbfZWsJ7MHY56sqt7hLQu3bxXHDnNhl8E9qI=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/ramendr/ramen/api v0.0.0-20241001141243-29d6f22ad237 h1:ig6ePD0yopC5Qi5BRmhsIsKaOkdsGXTSmG3HTYIpquo=
github.com/ramendr/ramen/api v0.0.0-20241001141243-29d6f22ad237/go.mod h1:nO6VM/+PEhcPGyFIQJdhY6ip822cA61PAy/s6IjenAA=
github.com/red-hat-storage/ocs-operator/services/provider/api/v4 v4.0.0-20240917115204-741b9d6f263d h1:RK/zCM6xRwyeJ06u6xSLEwl5Q1g/6EZRQmSgzbqleT0=
github.com/red-hat-storage/ocs-operator/services/provider/api/v4 v4.0.0-20240917115204-741b9d6f263d/go.mod h1:t9GJk69TGXABBF8fFPB+ImpbA9mJyRS86wW6+Qn8xHo=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
Expand Down Expand Up @@ -776,6 +778,8 @@ k8s.io/client-go v0.31.0 h1:QqEJzNjbN2Yv1H79SsS+SWnXkBgVu4Pj3CJQgbx0gI8=
k8s.io/client-go v0.31.0/go.mod h1:Y9wvC76g4fLjmU0BA+rV+h2cncoadjvjjkkIGoTLcGU=
k8s.io/code-generator v0.20.1/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg=
k8s.io/code-generator v0.23.3/go.mod h1:S0Q1JVA+kSzTI1oUvbKAxZY/DYbA/ZUb4Uknog12ETk=
k8s.io/component-base v0.31.0 h1:/KIzGM5EvPNQcYgwq5NwoQBaOlVFrghoVGr8lG6vNRs=
k8s.io/component-base v0.31.0/go.mod h1:TYVuzI1QmN4L5ItVdMSXKvH7/DtvIuas5/mm8YT3rTo=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
Expand Down
11 changes: 11 additions & 0 deletions hack/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

RESTART_EXIT_CODE=42

while true; do
./usr/local/bin/ocs-operator $@
EXIT_CODE=$?
if [ $EXIT_CODE -ne $RESTART_EXIT_CODE ]; then
exit $EXIT_CODE
fi
done
30 changes: 29 additions & 1 deletion internal/controller/storageclaim_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"encoding/json"
"fmt"
"reflect"
"sigs.k8s.io/controller-runtime/pkg/handler"
"slices"
"strings"
"time"
Expand All @@ -32,9 +33,11 @@ import (
csiopv1a1 "github.com/ceph/ceph-csi-operator/api/v1alpha1"
"github.com/go-logr/logr"
snapapi "github.com/kubernetes-csi/external-snapshotter/client/v6/apis/volumesnapshot/v1"
ramenv1alpha1 "github.com/ramendr/ramen/api/v1alpha1"
providerclient "github.com/red-hat-storage/ocs-operator/services/provider/api/v4/client"
corev1 "k8s.io/api/core/v1"
storagev1 "k8s.io/api/storage/v1"
extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand All @@ -56,6 +59,8 @@ const (

pvClusterIDIndexName = "index:persistentVolumeClusterID"
vscClusterIDIndexName = "index:volumeSnapshotContentCSIDriver"

drClusterConfigCRDName = "drclusterconfigs.ramendr.openshift.io"
)

// StorageClaimReconciler reconciles a StorageClaim object
Expand All @@ -64,6 +69,7 @@ type StorageClaimReconciler struct {
cache.Cache
Scheme *runtime.Scheme
OperatorNamespace string
AvailableCrds map[string]bool

log logr.Logger
ctx context.Context
Expand Down Expand Up @@ -110,12 +116,25 @@ func (r *StorageClaimReconciler) SetupWithManager(mgr ctrl.Manager) error {
bldr := ctrl.NewControllerManagedBy(mgr).
For(&v1alpha1.StorageClaim{}, builder.WithPredicates(generationChangePredicate)).
Owns(&storagev1.StorageClass{}).
Owns(&snapapi.VolumeSnapshotClass{})
Owns(&snapapi.VolumeSnapshotClass{}).
Watches(
&extv1.CustomResourceDefinition{},
&handler.EnqueueRequestForObject{},
builder.WithPredicates(
utils.NamePredicate(drClusterConfigCRDName),
utils.CrdCreateAndDeletePredicate(&r.log, drClusterConfigCRDName, r.AvailableCrds[drClusterConfigCRDName]),
),
builder.OnlyMetadata,
)

if utils.DelegateCSI {
bldr = bldr.Owns(&csiopv1a1.ClientProfile{}, builder.WithPredicates(generationChangePredicate))
}

if r.AvailableCrds[drClusterConfigCRDName] {
bldr = bldr.Owns(&ramenv1alpha1.DRClusterConfig{}, builder.WithPredicates(generationChangePredicate))
}

return bldr.Complete(r)
}

Expand Down Expand Up @@ -144,6 +163,15 @@ func (r *StorageClaimReconciler) Reconcile(ctx context.Context, req ctrl.Request
r.ctx = ctrllog.IntoContext(ctx, r.log)
r.log.Info("Reconciling StorageClaim.")

crd := &metav1.PartialObjectMetadata{}
crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
crd.Name = drClusterConfigCRDName
if err := r.Client.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
r.log.Error(err, "Failed to get CRD", "CRD", drClusterConfigCRDName)
return reconcile.Result{}, err
}
utils.AssertEqual(r.AvailableCrds[drClusterConfigCRDName], crd.UID != "", utils.ExitCodeThatShouldRestartTheProcess)

// Fetch the StorageClaim instance
r.storageClaim = &v1alpha1.StorageClaim{}
r.storageClaim.Name = req.Name
Expand Down
2 changes: 2 additions & 0 deletions pkg/utils/k8sutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ const CronScheduleWeekly = "@weekly"

const CSIReconcileEnvVar = "CSI_RECONCILE"

const ExitCodeThatShouldRestartTheProcess = 42

// GetOperatorNamespace returns the namespace where the operator is deployed.
func GetOperatorNamespace() string {
return os.Getenv(OperatorNamespaceEnvVar)
Expand Down
39 changes: 39 additions & 0 deletions pkg/utils/predicates.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package utils

import (
"github.com/go-logr/logr"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/predicate"
)

// Name Predicate return a predicate the filter events produced
// by resources that matches the given name
func NamePredicate(name string) predicate.Predicate {
return predicate.NewPredicateFuncs(func(obj client.Object) bool {
return obj.GetName() == name
})
}

func CrdCreateAndDeletePredicate(log *logr.Logger, crdName string, crdExists bool) predicate.Predicate {
return predicate.Funcs{
CreateFunc: func(_ event.CreateEvent) bool {
if !crdExists {
log.Info("CustomResourceDefinition %s was Created.", crdName)
}
return !crdExists
},
DeleteFunc: func(_ event.DeleteEvent) bool {
if crdExists {
log.Info("CustomResourceDefinition %s was Deleted.", crdName)
}
return crdExists
},
UpdateFunc: func(_ event.UpdateEvent) bool {
return false
},
GenericFunc: func(_ event.GenericEvent) bool {
return false
},
}
}
8 changes: 8 additions & 0 deletions pkg/utils/slices.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ limitations under the License.

package utils

import "os"

// Find returns the first entry matching the function "f" or else return nil
func Find[T any](list []T, f func(item *T) bool) *T {
for idx := range list {
Expand All @@ -26,3 +28,9 @@ func Find[T any](list []T, f func(item *T) bool) *T {
}
return nil
}

func AssertEqual[T comparable](actual T, expected T, exitCode int) {
if actual != expected {
os.Exit(exitCode)
}
}
Loading
Loading