-
Notifications
You must be signed in to change notification settings - Fork 19
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
Return a subscription from handleSubscription
#198
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -125,7 +125,8 @@ func (r *OperatorPolicyReconciler) Reconcile(ctx context.Context, req ctrl.Reque | |
return reconcile.Result{}, err | ||
} | ||
|
||
if err := r.handleSubscription(ctx, policy); err != nil { | ||
_, err = r.handleSubscription(ctx, policy) | ||
if err != nil { | ||
OpLog.Error(err, "Error handling Subscription") | ||
|
||
return reconcile.Result{}, err | ||
|
@@ -358,98 +359,106 @@ func buildOperatorGroup( | |
return operatorGroup, nil | ||
} | ||
|
||
func (r *OperatorPolicyReconciler) handleSubscription(ctx context.Context, policy *policyv1beta1.OperatorPolicy) error { | ||
func (r *OperatorPolicyReconciler) handleSubscription( | ||
ctx context.Context, policy *policyv1beta1.OperatorPolicy, | ||
) (*operatorv1alpha1.Subscription, error) { | ||
watcher := opPolIdentifier(policy.Namespace, policy.Name) | ||
|
||
desiredSub, err := buildSubscription(policy) | ||
if err != nil { | ||
return fmt.Errorf("error building subscription: %w", err) | ||
return nil, fmt.Errorf("error building subscription: %w", err) | ||
} | ||
|
||
foundSub, err := r.DynamicWatcher.Get(watcher, subscriptionGVK, desiredSub.Namespace, desiredSub.Name) | ||
if err != nil { | ||
return fmt.Errorf("error getting the Subscription: %w", err) | ||
return nil, fmt.Errorf("error getting the Subscription: %w", err) | ||
} | ||
|
||
if foundSub == nil { | ||
// Missing Subscription: report NonCompliance | ||
err := r.updateStatus(ctx, policy, missingWantedCond("Subscription"), missingWantedObj(desiredSub)) | ||
if err != nil { | ||
return fmt.Errorf("error updating status for a missing Subscription: %w", err) | ||
return nil, fmt.Errorf("error updating status for a missing Subscription: %w", err) | ||
} | ||
|
||
if policy.Spec.RemediationAction.IsEnforce() { | ||
err := r.Create(ctx, desiredSub) | ||
if err != nil { | ||
return fmt.Errorf("error creating the Subscription: %w", err) | ||
return nil, fmt.Errorf("error creating the Subscription: %w", err) | ||
} | ||
|
||
desiredSub.SetGroupVersionKind(subscriptionGVK) // Create stripped this information | ||
|
||
// Now it should match, so report Compliance | ||
err = r.updateStatus(ctx, policy, createdCond("Subscription"), createdObj(desiredSub)) | ||
if err != nil { | ||
return fmt.Errorf("error updating the status for a created Subscription: %w", err) | ||
return nil, fmt.Errorf("error updating the status for a created Subscription: %w", err) | ||
} | ||
} | ||
|
||
return nil | ||
return desiredSub, nil | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think returning something like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's possible... but I think that if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I might be overlooking something but is the point of this to reduce calls to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mostly. This would reduce calls to This can also return the "merged" subscription, regardless of inform/enforce, which hypothetically could be useful for some other healthcheck... I don't see a need for that yet, but it feels like it's easy enough to "do it right" now, so we don't have to worry about it later. For example if some other check used the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, I think that would be useful in general. For my specific case I'm only calling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should mention that I'm specifically thinking about the |
||
} | ||
|
||
// Subscription found; check if specs match | ||
desiredUnstruct, err := runtime.DefaultUnstructuredConverter.ToUnstructured(desiredSub) | ||
if err != nil { | ||
return fmt.Errorf("error converting desired Subscription to an Unstructured: %w", err) | ||
return nil, fmt.Errorf("error converting desired Subscription to an Unstructured: %w", err) | ||
} | ||
|
||
merged := foundSub.DeepCopy() // Copy it so that the value in the cache is not changed | ||
|
||
updateNeeded, skipUpdate, err := r.mergeObjects(ctx, desiredUnstruct, merged, string(policy.Spec.ComplianceType)) | ||
if err != nil { | ||
return fmt.Errorf("error checking if the Subscription needs an update: %w", err) | ||
return nil, fmt.Errorf("error checking if the Subscription needs an update: %w", err) | ||
} | ||
|
||
mergedSub := new(operatorv1alpha1.Subscription) | ||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(merged.Object, mergedSub); err != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just checked and I don't believe this will produce an error if there are unknown fields (e.g. version drift of different OLM versions). So this looks to be safe if you are just reading from it. |
||
return nil, fmt.Errorf("error converting the retrieved Subscription to the go type: %w", err) | ||
} | ||
|
||
if !updateNeeded { | ||
// FUTURE: Check more details about the *status* of the Subscription | ||
// For now, just mark it as compliant | ||
err := r.updateStatus(ctx, policy, matchesCond("Subscription"), matchedObj(foundSub)) | ||
if err != nil { | ||
return fmt.Errorf("error updating the status for an OperatorGroup that matches: %w", err) | ||
return nil, fmt.Errorf("error updating the status for an OperatorGroup that matches: %w", err) | ||
} | ||
|
||
return nil | ||
return mergedSub, nil | ||
} | ||
|
||
// Specs don't match. | ||
if policy.Spec.RemediationAction.IsEnforce() && skipUpdate { | ||
err = r.updateStatus(ctx, policy, mismatchCondUnfixable("Subscription"), mismatchedObj(foundSub)) | ||
if err != nil { | ||
return fmt.Errorf("error updating status for a mismatched Subscription that can't be enforced: %w", err) | ||
return nil, fmt.Errorf( | ||
"error updating status for a mismatched Subscription that can't be enforced: %w", err) | ||
} | ||
|
||
return nil | ||
return mergedSub, nil | ||
} | ||
|
||
err = r.updateStatus(ctx, policy, mismatchCond("Subscription"), mismatchedObj(foundSub)) | ||
if err != nil { | ||
return fmt.Errorf("error updating status for a mismatched Subscription: %w", err) | ||
return nil, fmt.Errorf("error updating status for a mismatched Subscription: %w", err) | ||
} | ||
|
||
if policy.Spec.RemediationAction.IsEnforce() { | ||
err := r.Update(ctx, merged) | ||
if err != nil { | ||
return fmt.Errorf("error updating the Subscription: %w", err) | ||
return nil, fmt.Errorf("error updating the Subscription: %w", err) | ||
} | ||
|
||
desiredSub.SetGroupVersionKind(subscriptionGVK) // Update stripped this information | ||
merged.SetGroupVersionKind(subscriptionGVK) // Update stripped this information | ||
|
||
err = r.updateStatus(ctx, policy, updatedCond("Subscription"), updatedObj(desiredSub)) | ||
err = r.updateStatus(ctx, policy, updatedCond("Subscription"), updatedObj(merged)) | ||
if err != nil { | ||
return fmt.Errorf("error updating status after updating the Subscription: %w", err) | ||
return nil, fmt.Errorf("error updating status after updating the Subscription: %w", err) | ||
} | ||
} | ||
|
||
return nil | ||
return mergedSub, nil | ||
} | ||
|
||
// buildSubscription bootstraps the subscription spec defined in the operator policy | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think returning a subscription inside of the logic that handles the
enforce
remediationAction type would be useful for futurehandler
functions. It would make sense for this function to return a subscription only if it was created successfully on the cluster.