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

✨ Initial support for Extension #598

Merged
merged 4 commits into from
Feb 21, 2024

Conversation

tmshort
Copy link
Contributor

@tmshort tmshort commented Jan 24, 2024

Fix #596

Based on ClusterExtension

Description

Reviewer Checklist

  • API Go Documentation
  • Tests: Unit Tests (and E2E Tests, if appropriate)
  • Comprehensive Commit Messages
  • Links to related GitHub Issue(s)

@tmshort tmshort requested a review from a team as a code owner January 24, 2024 21:30
@tmshort
Copy link
Contributor Author

tmshort commented Jan 24, 2024

Looking for feedback on the initial definition of Extension before hooking everything up.

Copy link

codecov bot commented Jan 24, 2024

Codecov Report

Attention: 163 lines in your changes are missing coverage. Please review.

Comparison is base (d51dfe6) 84.53% compared to head (8e39443) 74.35%.
Report is 15 commits behind head on main.

Files Patch % Lines
api/v1alpha1/zz_generated.deepcopy.go 0.00% 77 Missing ⚠️
internal/controllers/extension_controller.go 41.26% 33 Missing and 4 partials ⚠️
...nal/controllers/validators/extension_validators.go 0.00% 22 Missing ⚠️
api/v1alpha1/clusterextension_types.go 0.00% 10 Missing ⚠️
cmd/manager/main.go 0.00% 8 Missing and 1 partial ⚠️
api/v1alpha1/extension_types.go 20.00% 8 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main     #598       +/-   ##
===========================================
- Coverage   84.53%   74.35%   -10.18%     
===========================================
  Files          20       24        +4     
  Lines         931     1205      +274     
===========================================
+ Hits          787      896      +109     
- Misses        100      260      +160     
- Partials       44       49        +5     
Flag Coverage Δ
e2e 52.28% <18.97%> (-7.55%) ⬇️
unit 70.22% <36.88%> (-10.08%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Comment on lines 50 to 51
// Pause reconciliation on this Extension
Paused *bool `json:"paused,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

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

It is somewhat frowned upon to use bools in kubernetes APIs because there are many cases where a 3rd (or more) state creeps in.

Should we try to make this an enum-style string field with a oneOf validation?

Comment on lines 58 to 93
//+kubebuilder:validation:MaxLength:=64
//+kubebuilder:validation:Pattern:=^[a-z0-9]+([\.-][a-z0-9]+)*$
// +optional
// Location of installation TBD??
DefaultNamespace string `json:"defaultNamespace,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

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

Since extension is namespace-scoped, I wonder if we should start without this field in the API and just always use the install namespace as the "default namespace" to begin with.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 to using the install namespace as the default namespace. I'm not sure if there has been more discussion on implementing it yet, but maybe this can be repurposed as WatchNamespaces?

Copy link
Member

Choose a reason for hiding this comment

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

The App CR has defaultNamespace. I was thinking it would be helpful here, but I'm totally fine waiting to add that later.

Copy link
Member

Choose a reason for hiding this comment

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

I've definitely seen requirements about the operator in the namespace having different permissions than what is required to apply the operator to the cluster, so it seems useful to be able to manage the operator installation without a service account that can apply rbac in that namespace.

Copy link
Member

Choose a reason for hiding this comment

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

What are you proposing, Kevin?

Copy link
Member

Choose a reason for hiding this comment

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

Maybe I'm missing the context of this, but if we kept this field wouldn't that mean that if it's set to something other than the namespace the extension cr is applied to, we will template the namespace of manifests in the bundle to whatever this field is set to? I'm saying I see a use case for that.

//+kubebuilder:validation:MaxLength:=64
//+kubebuilder:validation:Pattern:=^[a-z0-9]+([\.-][a-z0-9]+)*$
// ServiceAccount name used to install this extension
ServiceAccountName string `json:"serviceAccountName,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Based on #595 it seems like this would be a required field

Copy link
Member

Choose a reason for hiding this comment

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

Correct

DefaultNamespace string `json:"defaultNamespace,omitempty"`

// Defintion of package to be installed
Package ExtensionPackage `json:"package,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like #596 was updated to prefer a "source" pattern. So something like:

Suggested change
Package ExtensionPackage `json:"package,omitempty"`
Source ExtensionSource `json:"source,omitempty"`

I imagine this would need to be a required field or have some validation to check that the source is "one of" X,Y,Z

Copy link
Member

Choose a reason for hiding this comment

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

Source is required. Only 1 of its field may be specified, and is required. We can do that with CEL validation.

Copy link
Member

Choose a reason for hiding this comment

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

Comment on lines 27 to 30
// Pause resolution of this Extension
ExtensionPausedTrue ExtensionPaused = "True"
// Peform resolution of this Extension
ExtensionPausedFalse ExtensionPaused = "False"
Copy link
Member

Choose a reason for hiding this comment

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

Sorry, should have been more specific earlier. What about something with:

  • Paused and Active enum values
  • Active would be default.

In the future, this would give us space to easily introduce another meaningful enum value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The spec named the field paused. Having the field and a value be the same makes little sense. Do you have a suggestion for new name?

Copy link
Member

Choose a reason for hiding this comment

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

I really like paused true/false and I'm not sure I'm convinced that in the future we'd want to expand paused with more values... but some brainstorming if we want to:

managed: active/paused
management.state: active/paused
reconcile: active/paused
reconciliation: active/paused

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wrote this as resolution rather than reconciliation, so thinking managed might be more appropriate.

Copy link
Member

Choose a reason for hiding this comment

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

I don't have a really strong opinion here. What I want to avoid is a situation where there is some other knob that we decide we need to add later that isn't completely orthogonal to spec.paused. I can't think of anything off hand, though. This does seem fairly cut and dry.

Not exactly the same, but the OLMv0 CatalogSource API has some fields that become inert based on the value of some other fields. Perhaps the main issue there is that we didn't add validation at the time that would prevent setting a field if something else made it inert.

api/v1alpha1/extension_types.go Outdated Show resolved Hide resolved
api/v1alpha1/extension_types.go Outdated Show resolved Hide resolved
api/v1alpha1/extension_types.go Outdated Show resolved Hide resolved
@tmshort
Copy link
Contributor Author

tmshort commented Jan 29, 2024

Ignoring the build failures (which will be fixed) is this looking like something we want to proceed with?

api/v1alpha1/extension_types.go Show resolved Hide resolved
api/v1alpha1/extension_types.go Show resolved Hide resolved
api/v1alpha1/extension_types.go Outdated Show resolved Hide resolved
@tmshort tmshort force-pushed the extension branch 3 times, most recently from ac9ad41 to e722512 Compare February 6, 2024 18:47
Copy link
Member

@joelanford joelanford left a comment

Choose a reason for hiding this comment

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

What's the thought on order of operations for fully switching over to Carvel? With this PR, we would have ClusterExtensions and Extensions both managing BundleDeployments.

And @varshaprasad96 is working on replacing BD with Carvel App.

Not sure what you all are thinking, but my hunch is that coding and review would be fastest with the following order:

  1. Add Extension API with no controller
  2. Varsha adds Extension controller with App support (essentially pretending like ClusterExtension API and controller do not exist).
  3. We remove ClusterExtension API and controller.

I'm worried that we'll spend unnecessary time writing code, updating tests, reviewing, and discussing/handling edge cases if we approach this as keeping both or implementing Extension+BundleDeployment.

@tmshort
Copy link
Contributor Author

tmshort commented Feb 6, 2024

I'm worried that we'll spend unnecessary time writing code, updating tests, reviewing, and discussing/handling edge cases if we approach this as keeping both or implementing Extension+BundleDeployment.

@joelanford
I've already plumbed everything up, and all unit/e2e tests are passing. It was mostly copied/referenced code. I think it's fine if the controller exists, because it create a behavior baseline.
The amount of work for adding kapp-controller won't change that much if the controller is provided now or later.

@joelanford
Copy link
Member

IMO, all of the changes that are made in this PR that make it possible to reuse code for both ClusterExtensions and Extensions is essentially adding an extra layer of abstraction that we won't want or need once we remove the ClusterExtension API.

Even just the time that folks will spend reviewing seems pretty steep (>5000 LoC change in this PR right now).

If we're going to have a Extension+BundleDeployment controller in place in this transition, it seems like it might be easier if we order things somewhat like this:

  1. rename ClusterExtension to Extension and make it namespace-scoped, but otherwise no changes to the API. Also make whatever changes are necessary in the controller (if any) to account for this being namespace-scoped.
  2. swap out Rukpak for Carvel
  3. Update Extension API to match what we have here.

Any maybe 2 and 3 can be reversed?

@varshaprasad96
Copy link
Member

varshaprasad96 commented Feb 7, 2024

Adding some thoughts:

  1. swap out Rukpak for Carvel

How long do we want to support Rukpak and Kapp controller side-by-side? Based on the previous discussions, as I understand we want kapp-ctrl to be under feature gate, and still support Rukpak before making a complete swap.

If that is going to be the case, the initial sequence of steps seem more apt - #598 (review), to avoid supporting an intermediate Extension+BD at all, which users can find confusing - a namespace scoped API supporting 2 appliers underneath, that support different scoping. Though there would be some rework, it would keep things clearer in terms of

a. ClusterExtension+Rukpak
b. Extension+Kapp.
Once we are confident enough with (b), we remove (a) in entirety (along with any relevant tests).

If there is going to be a complete immediate swap without needing to support both Rukpak and Kapp, we could do #598 (comment). Would prefer supporting Carvel first with bare minimal specs in Extension API, so that we can break down and follow up with requirements to complete (3) in parallel.

@tmshort
Copy link
Contributor Author

tmshort commented Feb 13, 2024

I didn't add a feature gate (although I thought about it). But I'm guessing your concern has to do with any additional parameters (e.g. namespace?) that is necessary for resolution of the software to be installed. I can certainly reduce the scope of the reconciler to not include resolution.

Copies ClustersExtension functionality

`ServiceAccountName` doesn't do anything yet.

Signed-off-by: Todd Short <tshort@redhat.com>
Comment on lines 126 to 136
if features.OperatorControllerFeatureGate.Enabled(features.EnableExtensionApi) {
if err = (&controllers.ExtensionReconciler{
Client: cl,
BundleProvider: catalogClient,
Scheme: mgr.GetScheme(),
Resolver: resolver,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Extension")
os.Exit(1)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

One of the implications with not even adding a reconciler for the Extension API to the controller manager is that if this feature gate is disabled, creating an Extension resource will silently do nothing. From a UX perspective I think it would make sense to still add the reconciler but when the feature gate is disabled we simply add a status condition that states something along the lines of "Reconciliation skipped. feature gate for the Extension API is disabled. The Extension API is an alpha feature that is still in development. To enable reconciliation use the flag --feature-gates=EnableExtensionApi=true".

Doing this would at least signal to an end user that it is currently in a "do nothing" state and how to enable it.

Copy link
Contributor

Choose a reason for hiding this comment

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

That being said, I'm also not sure of any API versioning constraints that come with adding a status condition for this. Definitely something to think about regarding the pros/cons

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I'm a bit torn. on where to put the feature gate.

Copy link
Member

@varshaprasad96 varshaprasad96 Feb 14, 2024

Choose a reason for hiding this comment

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

The ideal scenario would be to not have the Extension CRD applied if the feature gate is disabled - but I don't think that's something which is possible here, since the CRDs are applied before the controller pod is created. Instead of setting up the reconciler by default and adding the overhead of watching Extension resources, what do you all think about adding a log/warning during startup, mentioning the value of the feature gate flag, and explicitly stating something on the lines of - "feature gate flag for ExtensionAPI set to false, no action will be taken by operator controller if Extension object is created". That should to some extent satisfy the UI difficulties without having us to take more effort on it for now and at the same time not be a surprise for the user that nothing is happening when Extension is created?

Copy link
Contributor

Choose a reason for hiding this comment

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

@varshaprasad96 I think that assumes a user who might create the Extension resource would have an understanding to go and look at the logs of the operator-controller pod and explicitly find that singular log message.

Throwing a message on the status is more immediately visible IMO and to me doesn't feel like a bunch of overhead. I'm mainly approaching this from what I would want as a user and I would much prefer seeing a status be set than having to find the pod that is running the controller manager, get the logs, and search the logs for any indication as to why nothing happened

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@everettraven has a point, if your extension isn't running, you're going to look at your extension first, and not necessarily a pod to which you don't have log access to.

Copy link
Member

Choose a reason for hiding this comment

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

Some thoughts on why this suggestion:

I think that assumes a user who might create the Extension resource would have an understanding to go and look at the logs of the operator-controller pod and explicitly find that singular log message.

I would expect that users who create Extension resources have the understanding of troubleshooting at this stage, which includes checking logs when something doesn't work as expected - this is particularly considering the fact that afaik there is no one trying to use v1 in production in near future, at least till we make kapp-ctrl switch -scheduled soon.

That being said, I understand and completely agree that having just a log line - that too in an o-c pod that the user trying to install the package, ideally should not concern with - is not the perfect UX. This is to avoid - both the overhead of having an additional reconciler watch extension and other relevant resources on cluster which is not necessary, and us spending time on an API field that could turn out to be temporary in very near future. On a quick search upstream found an example of one of the optional controllers enabled only when the feature gate is present.

Signed-off-by: Todd Short <tshort@redhat.com>
//nolint:unparam
func (r *ExtensionReconciler) reconcile(_ context.Context, ext *ocv1alpha1.Extension) (ctrl.Result, error) {
// Don't do anything if Paused
if ext.Spec.Managed == ocv1alpha1.ManagedStatePaused {
Copy link
Member

Choose a reason for hiding this comment

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

Can we add a log here stating no reconciliation done because the managedState is set to paused?

Copy link
Member

@joelanford joelanford Feb 14, 2024

Choose a reason for hiding this comment

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

For follow-up, check in other popular Kubernetes projects and see if there is a pattern where a Paused condition is set.

// Generate reconcile requests for all extensions affected by a catalog change
func extensionRequestsForCatalog(c client.Reader, logger logr.Logger) handler.MapFunc {
return func(ctx context.Context, _ client.Object) []reconcile.Request {
// no way of associating an extension to a catalog so create reconcile requests for everything
Copy link
Member

Choose a reason for hiding this comment

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

Given we are not mapping catalog and extension, and creating reconcile requests for all extensions, I don't think we need this mapping func. Watching all catalogs should be enough (in the current state).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe this is still necessary as the comment says, there's no way to indicate ownership due to the namespace scope of Extension. I can look, but this is how ClusterExtension does it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I figured out the correct method.

Comment on lines 5 to 11
labels:
app.kubernetes.io/name: clusterrole
app.kubernetes.io/instance: extension-viewer-role
app.kubernetes.io/component: rbac
app.kubernetes.io/created-by: operator-controller
app.kubernetes.io/part-of: operator-controller
app.kubernetes.io/managed-by: kustomize
Copy link
Member

Choose a reason for hiding this comment

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

Nit: drop all these labels (here and in the editor role). These are setup by SDK/Kubebuilder, right? I don't think they provide any real value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I remove them, they might be re-added?

Copy link
Member

Choose a reason for hiding this comment

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

I'm guessing this is part of operator-sdk create api? So no they would not be re-added.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure, but I'll try; there definitely a build process that regenerates some of these types of things.

Comment on lines 26 to 31
- apiGroups:
- olm.operatorframework.io
resources:
- extensions/status
verbs:
- get
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Is get a valid verb on the CRD status subresource? I'm fairly sure it isn't and this rule accomplishes nothing. (Is this another SDK/Kubebuilder-ism?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I believe kubebuilder did this, and might put it back...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why would kubebuilder put on an invalid verb for a resource such as this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

client.Status().Get() does not seem to exist... so perhaps you can't get it.

Copy link
Member

Choose a reason for hiding this comment

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

I'll dig in kubebuilder code. But I bet just an uninformed addition to the generation that seemed like a good idea.

Copy link
Member

Choose a reason for hiding this comment

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

Wow, it has been there for a very long time (5 years). I suspect it was overlooked originally and is otherwise completely inert so no one has ever noticed.

Comment on lines 22 to 27
- apiGroups:
- olm.operatorframework.io
resources:
- extensions/status
verbs:
- get
Copy link
Member

Choose a reason for hiding this comment

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

Same question as above about get on the status subresource.

resources:
- extensions/status
verbs:
- get
Copy link
Member

Choose a reason for hiding this comment

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

And here.

Comment on lines 4 to 9
labels:
app.kubernetes.io/name: extension
app.kubernetes.io/instance: extension-sample
app.kubernetes.io/part-of: operator-controller
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/created-by: operator-controller
Copy link
Member

Choose a reason for hiding this comment

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

Also remove these labels?

Copy link
Member

Choose a reason for hiding this comment

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

Do these actually get included in the kustomize output? It looks like not because they are not listed in the kustomization.yaml file (neither are the ClusterExtension roles).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No idea, but they were generated... we can remove them later if deemed necessary?

Copy link
Member

Choose a reason for hiding this comment

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

Sure.

Copy link
Member

Choose a reason for hiding this comment

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

I guess I'd suggest adding them to the kustomization file?

(It looks like I have a few issues to open in Kubebuilder 😅 )

}
}
return nil
}
Copy link
Member

Choose a reason for hiding this comment

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

Ideally, we would not need reconcile-time validators at all because we instead have validation done via CRD schema validation.

I won't push to remove this validation code now, but I think we should capture a follow-up that removes it and then beefs up tests of the CRD validation (if they aren't already beefy) to make sure our CRD schema validation functions catch everything we expect. If anything slips through, it likely fails anyway somewhere else during reconciliation.

}
require.NoError(t, cl.Create(ctx, namespace))

t.Log("By injecting creating a client with the bad clusterextension CR")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
t.Log("By injecting creating a client with the bad clusterextension CR")
t.Log("By injecting creating a client with the bad extension CR")

Source: ocv1alpha1.ExtensionSource{
Package: &ocv1alpha1.ExtensionSourcePackage{
Name: pkgName,
Version: "1.2.3-123abc_def", // bad semver that matches the regex on the CR validation
Copy link
Member

Choose a reason for hiding this comment

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

This passes our CRD schema validation, but does not parse with the masterminds parser? If that's the case, how hard would it be to update the CRD pattern to disallow this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was from cluster extension (originally operator), we might have to look at the original PR to understand why... my recollection was complexity of the regex, maybe?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looking further into the test, it purposefully bypasses CR validation, and exercises the validation code.

Copy link
Member

Choose a reason for hiding this comment

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

Seems... kinda useless if we already have CRD validations and tests for them. But happy to revisit in a follow-up.

p.Channel = r.Spec.Channel
p.Name = r.Spec.PackageName
p.Version = r.Spec.Version

Copy link
Member

Choose a reason for hiding this comment

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

Add UpgradeConstraintPolicy here too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not needed yet, we have no processing for it in Extension

Copy link
Member

Choose a reason for hiding this comment

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

I was thinking just in terms of symmetry with what you'd get from Extension.GetPackageSpec().

Copy link
Member

Choose a reason for hiding this comment

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

Should we consider removing GetPackageSpec and ExtensionInterface in general? It looks like all the functions right now receive concrete types. Someday, and that day may never come, we will add an interface. But until that day, we should be fine without it.

Comment on lines 177 to 179
func (r *ClusterExtension) GetUpgradeConstraintPolicy() UpgradeConstraintPolicy {
return r.Spec.UpgradeConstraintPolicy
}
Copy link
Member

Choose a reason for hiding this comment

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

Drop this since UpgradeConstraintPolicy is now part of the package struct?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The interface function is not being used, so I'm removing it

Signed-off-by: Todd Short <tshort@redhat.com>
Copy link
Member

@m1kola m1kola left a comment

Choose a reason for hiding this comment

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

I left a few questions and suggestions.

Ask for the next time - can we please split large PRs into smaller ones? For this PR split could look something like this:

  1. Refactor existing controllers to extract generic parts
  2. Add a new Extension type & generate manifests for it
  3. Introduce a new controller for Extension

It is easier to review smaller PRs.

P.S: I'm guilty of making large PRs myself, but I'm trying :)

Comment on lines +173 to +175
func (r *ClusterExtension) GetUID() types.UID {
return r.ObjectMeta.GetUID()
}
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to do that? ObjectMeta is embedded and I believe GetUID() should be available without overriding. Or am I missing something?

internal/internal.go Outdated Show resolved Hide resolved
Comment on lines +25 to +44
type ExtensionInterface interface {
GetPackageSpec() *ocv1alpha1.ExtensionSourcePackage
GetUID() types.UID
}

func ExtensionArrayToInterface(in []ocv1alpha1.Extension) []ExtensionInterface {
ei := make([]ExtensionInterface, len(in))
for i := range in {
ei[i] = &in[i]
}
return ei
}

func ClusterExtensionArrayToInterface(in []ocv1alpha1.ClusterExtension) []ExtensionInterface {
ei := make([]ExtensionInterface, len(in))
for i := range in {
ei[i] = &in[i]
}
return ei
}
Copy link
Member

Choose a reason for hiding this comment

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

Where is interface and these conversion functions are being used? Is it a leftover from before scope reduction? If so - should we get rid of this for now?

p.Channel = r.Spec.Channel
p.Name = r.Spec.PackageName
p.Version = r.Spec.Version

Copy link
Member

Choose a reason for hiding this comment

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

Should we consider removing GetPackageSpec and ExtensionInterface in general? It looks like all the functions right now receive concrete types. Someday, and that day may never come, we will add an interface. But until that day, we should be fine without it.

@joelanford
Copy link
Member

Big +1 to @m1kola 's request to have smaller incremental PRs. I think reviews/merges would move a lot faster and will be key to unblocking others as well.

Copy link
Member

@joelanford joelanford left a comment

Choose a reason for hiding this comment

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

I think this PR is still a bit large to be able to engage in high fidelity review, and I'm feeling a bit of review fatigue with all of the moving parts.

However, I would like to unblock further work, so perhaps we could merge what we have and then follow back up with smaller PRs that cover the following:

@tmshort
Copy link
Contributor Author

tmshort commented Feb 20, 2024

@joelanford are we good to merge, with issues created for those items listed?

Copy link
Member

@varshaprasad96 varshaprasad96 left a comment

Choose a reason for hiding this comment

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

@tmshort Just a small update comment on samples based on recent changes made in the PR.

paused: false
serviceAccountName: extension-sa
defaultNamespace: extension-sample
package:
Copy link
Member

Choose a reason for hiding this comment

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

Was working based of this PR, realized that this sample need to be updated according to the recent changes made in the spec.

Copy link
Member

Choose a reason for hiding this comment

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

Basically this:

apiVersion: olm.operatorframework.io/v1alpha1
kind: Extension
metadata:
  labels:
    app.kubernetes.io/name: extension
    app.kubernetes.io/instance: extension-sample
    app.kubernetes.io/part-of: operator-controller
    app.kubernetes.io/managed-by: kustomize
    app.kubernetes.io/created-by: operator-controller
  name: extension-sample
  namespace: extension-sample
spec:
  paused: false
  serviceAccountName: extension-sa
  source:
    package:
      name: argcocd-operator
      version: <>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are you talking about the labels, or defaultNamespace?

Copy link
Member

Choose a reason for hiding this comment

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

Not the labels, just the spec. Removal of default namespace, embedding package inside source and also renaming paused to managed.
I was trying to use this sample to test extensions with App CR, which is when realized that some of the fields are not upto date with the what is present in CRD.

@joelanford
Copy link
Member

You have the all clear from me to merge. We can also capture Varsha's sample update in a follow up as well as far as I'm concerned.

@joelanford joelanford mentioned this pull request Feb 21, 2024
16 tasks
@joelanford
Copy link
Member

I've captured the follow-ups in the epic issue. Adding this one to the queue now.

@joelanford joelanford added this pull request to the merge queue Feb 21, 2024
Merged via the queue into operator-framework:main with commit 35801df Feb 21, 2024
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add Extension API
8 participants