Skip to content

Commit

Permalink
chore(feature-tracker): simplifies struct handling (opendatahub-io#1092)
Browse files Browse the repository at this point in the history
* chore(feature-tracker): simplifies struct handling

Refactors FeatureTracker related functions to plain functions
instead of Feature receivers This improves separation of concerns
and eliminates unnecessary coupling.

Revised the FeatureTracker attachment process to the owning Features.

* fix: merge conflict

(cherry picked from commit 2d2a56a)
  • Loading branch information
bartoszmajsak authored and VaishnaviHire committed Jul 24, 2024
1 parent e010339 commit c1d3cc0
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 39 deletions.
8 changes: 2 additions & 6 deletions pkg/feature/feature.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,11 @@ func (f *Feature) Apply(ctx context.Context) error {
if err != nil {
return err
}
errGet := getFeatureTrackerIfAbsent(ctx, f)
if errGet == nil {
return f.Cleanup(ctx)
}

return client.IgnoreNotFound(errGet)
return f.Cleanup(ctx)
}

if trackerErr := f.createFeatureTracker(ctx); trackerErr != nil {
if trackerErr := createFeatureTracker(ctx, f); trackerErr != nil {
return trackerErr
}

Expand Down
70 changes: 37 additions & 33 deletions pkg/feature/feature_tracker_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,26 @@ func (e *withConditionReasonError) Error() string {
return e.err.Error()
}

// createFeatureTracker instantiates FeatureTracker for a given Feature. It's a cluster-scoped resource used
// to track creation and removal of all owned resources which belong to this Feature.
// All resources which particular feature is composed of will have this object attached as an OwnerReference.
func (f *Feature) createFeatureTracker(ctx context.Context) error {
tracker, err := f.getFeatureTracker(ctx)
if k8serr.IsNotFound(err) {
if err := f.Client.Create(ctx, tracker); err != nil {
return err
// createFeatureTracker creates a FeatureTracker, persists it in the cluster,
// and attaches it to the provided Feature instance.
func createFeatureTracker(ctx context.Context, f *Feature) error {
tracker, errGet := getFeatureTracker(ctx, f)
if client.IgnoreNotFound(errGet) != nil {
return errGet
}

if k8serr.IsNotFound(errGet) {
tracker = featurev1.NewFeatureTracker(f.Name, f.Spec.AppNamespace)
tracker.Spec = featurev1.FeatureTrackerSpec{
Source: *f.Spec.Source,
AppNamespace: f.Spec.AppNamespace,
}
if errCreate := f.Client.Create(ctx, tracker); errCreate != nil {
return errCreate
}
} else if err != nil {
return err
}

if gvkErr := f.ensureGVKSet(tracker); gvkErr != nil {
if gvkErr := ensureGVKSet(tracker, f.Client.Scheme()); gvkErr != nil {
return gvkErr
}

Expand All @@ -49,40 +55,38 @@ func (f *Feature) createFeatureTracker(ctx context.Context) error {
return nil
}

// removeFeatureTracker removes the FeatureTracker associated with the provided Feature instance if one exists in the cluster.
func removeFeatureTracker(ctx context.Context, f *Feature) error {
if err := getFeatureTrackerIfAbsent(ctx, f); err != nil {
return client.IgnoreNotFound(err)
associatedTracker := f.Tracker
if associatedTracker == nil {
// Check if it is persisted in the cluster, but Feature do not have it attached
if tracker, errGet := getFeatureTracker(ctx, f); client.IgnoreNotFound(errGet) != nil {
return errGet
} else {
associatedTracker = tracker
}
}

if associatedTracker != nil {
return client.IgnoreNotFound(f.Client.Delete(ctx, associatedTracker))
}

return deleteTracker(ctx, f)
return nil
}

func (f *Feature) getFeatureTracker(ctx context.Context) (*featurev1.FeatureTracker, error) {
func getFeatureTracker(ctx context.Context, f *Feature) (*featurev1.FeatureTracker, error) {
tracker := featurev1.NewFeatureTracker(f.Name, f.Spec.AppNamespace)

tracker.Spec = featurev1.FeatureTrackerSpec{
Source: *f.Spec.Source,
AppNamespace: f.Spec.AppNamespace,
if errGet := f.Client.Get(ctx, client.ObjectKeyFromObject(tracker), tracker); errGet != nil {
return nil, errGet
}

err := f.Client.Get(ctx, client.ObjectKeyFromObject(tracker), tracker)

return tracker, err
}

func deleteTracker(ctx context.Context, f *Feature) error {
return client.IgnoreNotFound(f.Client.Delete(ctx, f.Tracker))
}

func getFeatureTrackerIfAbsent(ctx context.Context, f *Feature) error {
var err error
f.Tracker, err = f.getFeatureTracker(ctx)
return err
return tracker, nil
}

func (f *Feature) ensureGVKSet(obj runtime.Object) error {
func ensureGVKSet(obj runtime.Object, scheme *runtime.Scheme) error {
// See https://github.com/kubernetes/client-go/issues/308
gvks, unversioned, err := f.Client.Scheme().ObjectKinds(obj)
gvks, unversioned, err := scheme.ObjectKinds(obj)
if err != nil {
return fmt.Errorf("failed to get group, version, & kinds for object: %w", err)
}
Expand Down

0 comments on commit c1d3cc0

Please sign in to comment.