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

Create a CSV webhook #516

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

Conversation

iamniting
Copy link
Member

@iamniting iamniting commented Jan 15, 2025

Signed-off-by: Nitin Goyal nigoyal@redhat.com

Copy link
Contributor

openshift-ci bot commented Jan 15, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: iamniting

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jan 15, 2025
@iamniting iamniting force-pushed the webhook branch 3 times, most recently from a57ca02 to 263ec5e Compare January 15, 2025 10:05
@@ -25,6 +25,7 @@ namePrefix: odf-operator-
# endpoint w/o any authn/z, please comment the following line.
patchesStrategicMerge:
- manager_auth_proxy_patch.yaml
- manager_webhook_patch.yaml
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this required?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has webhook related changes port and volume details.

Comment on lines 55 to 96
csvWebhook := admrv1.MutatingWebhook{
Name: WebhookName,
ClientConfig: admrv1.WebhookClientConfig{
Service: &admrv1.ServiceReference{
Name: WebhookServiceName,
Path: ptr.To(odfwebhook.WebhookPath),
Port: ptr.To(int32(443)),
},
},
Rules: []admrv1.RuleWithOperations{
{
Rule: admrv1.Rule{
APIGroups: []string{"operators.coreos.com"},
APIVersions: []string{"v1alpha1"},
Resources: []string{"clusterserviceversions"},
Scope: ptr.To(admrv1.NamespacedScope),
},
Operations: []admrv1.OperationType{admrv1.Create},
},
},
SideEffects: ptr.To(admrv1.SideEffectClassNone),
TimeoutSeconds: ptr.To(int32(30)),
AdmissionReviewVersions: []string{"v1"},
// fail the validation if webhook can't be reached
FailurePolicy: ptr.To(admrv1.Fail),
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is recreated in every func invocation, why can't move this to a template and deep copy whatever is required?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added as a variable.

Comment on lines 128 to 155
webhookService := corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: WebhookServiceName,
Namespace: operatorNamespace,
},
Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{
{
Name: "https",
Port: 443,
Protocol: corev1.ProtocolTCP,
TargetPort: intstr.FromInt32(9443),
},
},
Selector: map[string]string{
"app.kubernetes.io/name": "odf-operator",
},
Type: corev1.ServiceTypeClusterIP,
},
}

svc := &corev1.Service{
ObjectMeta: webhookService.ObjectMeta,
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is recreated in every func invocation, why can't move this to a template and deep copy whatever is required?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added as a variable.

@leelavg
Copy link
Contributor

leelavg commented Feb 11, 2025

does this PR needs a push? where are you registering the webhook?

@iamniting
Copy link
Member Author

does this PR needs a push? where are you registering the webhook?

No it is getting created in controllers/storagesystem_controller.go and controllers/subscription_controller.go

@leelavg
Copy link
Contributor

leelavg commented Feb 24, 2025

does this PR needs a push? where are you registering the webhook?

No it is getting created in controllers/storagesystem_controller.go and controllers/subscription_controller.go

  • trying one more time, you have a type created in webhook/csv.go which has SetupWebhookWithManager method defined and I'm unable to find where this method was called.

@iamniting
Copy link
Member Author

does this PR needs a push? where are you registering the webhook?

No it is getting created in controllers/storagesystem_controller.go and controllers/subscription_controller.go

  • trying one more time, you have a type created in webhook/csv.go which has SetupWebhookWithManager method defined and I'm unable to find where this method was called.

I fixed it, It was missed, It is called in the main.

@iamniting iamniting force-pushed the webhook branch 6 times, most recently from eaf99a2 to 94351a1 Compare March 11, 2025 16:43
@iamniting iamniting requested a review from leelavg March 11, 2025 16:53
kind: Service
metadata:
annotations:
service.beta.openshift.io/serving-cert-secret-name: webhook-server-cert
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better to have a prefix for this secret as well as other operators could be using generic names.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renamed it to odf-operator-webhook-server-cert

- get
- list
- update
- watch
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we also need delete perms to delete the webhook upon DF uninstallation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who will delete this? We can not even have an owner ref added to the webhook.

func(ctx context.Context, obj client.Object) []reconcile.Request {
logger := log.FromContext(ctx)
ssList := &odfv1alpha1.StorageSystemList{}
err := r.Client.List(ctx, ssList, &client.ListOptions{Namespace: r.OperatorNamespace})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
err := r.Client.List(ctx, ssList, &client.ListOptions{Namespace: r.OperatorNamespace})
err := r.Client.List(ctx, ssList, client.InNamespace(r.OperatorNamespace)

i think using cmd construction options is more ergonomically

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

if err != nil {
return ctrl.Result{}, err
}

err = r.ensureSubscriptions(logger, req.NamespacedName.Namespace)
err = ensureWebhook(r.ctx, r.Client, logger, r.OperatorNamespace)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is webhook deployment in two controllers?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Subscriptions are handled from these 2 controllers. any of these can be triggered first, and we need to make sure we have the webhook before subscriptions.

err := mgr.Add(manager.RunnableFunc(func(ctx context.Context) error {

logger := log.FromContext(ctx)
err := ensureWebhook(ctx, r.Client, logger, r.OperatorNamespace)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

third instance of same reconcile function, Runnable runs in parallel to all reconcilers and doesn't have any priority afair.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should not cause any issues i believe, This was created so that even if we hit other issues, we still create the webhook and odf-deps subs.

WebhookPath = "/mutate-operators-coreos-com-v1alpha1-csv"
)

var (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vars' declared here should form a template w/ a facility to change the names and fill the info dynamically during reconcile.

better have only servicespec here and in webhook no name, namespace selector which'll be replaced in a single place.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will be the benefits of that?

return admission.PatchResponseFromRaw(req.Object.Raw, marshaledInstance)
}

func (r *ClusterServiceVersionDefaulter) getOldCsvReplicas(instance *opv1a1.ClusterServiceVersion) (int32, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rather than instance, csv is more discoverable as param var.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would prefer instance, because that is being used and created by scaffolding mostly at controller layers.

webhook/csv.go Outdated
}

for _, pkgName := range controllers.PkgNames {
if strings.HasPrefix(instance.ObjectMeta.Name, pkgName) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ObjectMeta and TypeMeta is embedded into the struct and could directly use .Name

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return 0, nil
}

func (r *ClusterServiceVersionDefaulter) mutateCsv(instance *opv1a1.ClusterServiceVersion, replicas *int32) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need a func here, this is neither a single unit nor being called multiple times.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This func is the place where all the changes are made to the csv. This func is called Default in scafolding. It is also easy to track that what and where changes are made to the csv.


func (r *ClusterServiceVersionDefaulter) getOldCsvReplicas(instance *opv1a1.ClusterServiceVersion) (int32, error) {

if instance.Spec.Replaces == "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so this is a new operator from this release and should we also check if we have the name/package in our records or else this will always stay scaled down?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is a new package, we should scale down by default, We should scale it up by the controller if needed.

Signed-off-by: Nitin Goyal <nigoyal@redhat.com>
Signed-off-by: Nitin Goyal <nigoyal@redhat.com>
Signed-off-by: Nitin Goyal <nigoyal@redhat.com>
Signed-off-by: Nitin Goyal <nigoyal@redhat.com>
Copy link
Contributor

openshift-ci bot commented Mar 13, 2025

@iamniting: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/ci-bundle-odf-dependencies-bundle 94351a1 link true /test ci-bundle-odf-dependencies-bundle
ci/prow/odf-operator-e2e-aws 79473fd link true /test odf-operator-e2e-aws

Full PR test history. Your PR dashboard.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants