-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Handle external API types explicitly in create api
#1999
Comments
I'd like to make a few considerations over this one:
Iin POV the command
Where the webhook would upstatde and the PROJECT file will have the resource info without api and a controller.
Kubebuilder only supports core types and the APIs scaffolded in the project by default unless you manually change the files you will be unable to work with external-types. I mean, it is not really supported by the tool since users are able to do that only if they customize the scaffolds manually via workarounds.
PROJECT file
post subcommand action
controller main.go We will need to add the schema before starts the manager. suite_test.go for controller and webhooks import (
...
routev1 "github.com/openshift/api/route/v1" // see {{path}}
...
)
....
var _ = BeforeSuite(func(done Done) {
...
err = routev1.AddToScheme(scheme.Scheme)
Expect(err).NotTo(HaveOccurred())
...
} Also, shows that we need to do a change in the CRDDirectoryPath for this case: See kubernetes-sigs/controller-runtime#1191
We need to check that. |
This comment was marked as outdated.
This comment was marked as outdated.
That requires a few more caveats. It was identified in the scenario (operator-framework/operator-sdk#4747) To scaffold a webhook for an external/core type:
|
Webhooks can not be created for external types with the higher level abstraction of controller-runtime (which |
Could you describe why not? An external type is exactly the same as any api/type created in the operator. The only difference is that is not defined in the project and outside. However, both are CRDs. Are you trying to describe that webhooks have a limitation for core types? could you please add more references about that here to share your thoughts? |
@camilamacedo86 you cannot define methods on an external type, since the Go project does not define the type. For example, you cannot define var _ admission.Validator = &corev1.Pod{}
func (t *corev1.Pod) ValidateCreate() error {
...
} |
The Note that indeed we need an behaviour/implementation-specific for each scenario, |
All core types are external types in this context. The problem encountered by the above example is the same for all external types. |
Sorry, I am afraid that I do not agree with that. For both scenarios, we are able to accomplish the goal. However, for each one, we need to address its caveats. For example, see here the kb documentation over how to create webhooks for core types. (https://book.kubebuilder.io/reference/webhook-for-core-types.html) |
Can you explain why they are different (not considering how they are represented in PROJECT right now)? |
Just saying this documentation is incomplete. It would be great to support 'core types'/'types not fulfilling interfaces'. It's quite doable ATM but requires some manual work. I'm happy to help with that if you need a hand. |
Coming from #2141 (comment)
Do I understand correctly that external types not implementing |
Hi @Adirio, @estroz, @kopiczko, My point here is that an external type is NOT a core type and they have not the same bahaviour. For example: External type can be a CRD that is implemented in Operator A and used in the B. In this common case, the scaffold for the external types can be exactly the same as that one that is done for the APIs/CRD owned by the project. However, please let me know if you see any reason for that does not be true. Then, in POV we have the following scenarios:
I hope that clarifies. |
@camilamacedo86 thanks for clarifying. There are definitely cases where external-types are not owned. One example my company is doing is setting default I'm also not sure if it feels right to have the controller logic outside the controller repository. In such scenario updating the type's repository dependency would also change the controller behaviour and this may make things more difficult to track. It also feels more rigid to me. E.g. someone may want to write a separate admission controllers for different providers. Having said all of that a support for even the most straight forward scenario like "external == owned" would be great, but it could lead to users generating webhook for a core type and then running |
Hi @kopiczko, Thank you for your reply.
In the example, the controller logic is in the project. The CRD definition is that not. The controller will reconcile a type that is not defined by the project only that. Because of this, we call external type.
We can easily identify what is a core-type or not. It is mapped in the project. See:https://github.com/kubernetes-sigs/kubebuilder/blob/master/pkg/plugins/golang/options.go#L27-L53 The only scenario that seems to be missing here to digger further is an external type such as OCP route API. How a webhook should be a scaffold for that,? |
Sorry @camilamacedo86 I abuse the word "controller".
Here I meant "admission controller". So "controller logic" == "webhook logic".
That was my whole point. If that scenario is not supported then users may end up with generating something for a core type and replacing imports. How would you like to scaffold a webhook for a core type? Wouldn't the same scaffolding work for non-core non-owned? |
@kopiczko yes, and @camilamacedo86 that is what I meant by "All core types are external types in this context". The solution suggested in the docs will work for core types right now. For other external types, differentiation from owned types is needed first so the CLI "knows" which implementation to scaffold. Side note: #833 talks about generally allowing low-level webhook scaffolding, which I think means creating a |
Hi @camilamacedo86 @estroz, I was pondering around a bit and have some ideas. What is the best way to discuss how this webhook scaffolding would look like? Is it fine to describe it very briefly here and then discuss the rest in a draft PR? |
Slack for early discussion can also be used, add me also to the conversation |
It is important because many users constantly ask and need to do this. Therefore, because the tool does not handle this scenario it is leading to misunderstandings and wrong assumptions. Because of this, I am adding the priority label on this one. **Summary **
@jmrodri I think we have been not working on this one. So, unassign you from this one so that we can have the opportunity to see if someone from the community can help us out. However, if you are looking at that then, please feel free to re-assign it to yourself. |
Using the same set of tools to complete the development of webhook and controller has greatly improved the efficiency of development for developers, and the readability and maintainability of the developed code is greatly improved when everyone uses the same set of tools, because we all follow the same set of standards In a real development scenario, we would develop a custom controller based on our scenario, but for us the more common scenario would be webhooks because there are already so many mature and good controllers in the community that there is no need to repeat development We are the Infrastructure Department. In order to integrate the capabilities of other components of the infrastructure, we usually need to perform patch behavior on other crd resources. For example:
so Examples of Using code 1. run the webhook build command$ kubebuilder create webhook \
--group argoproj.io \
--version v1alpha1 \
--kind Workflow \
--webhook-type external \
--external-import "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" \
--defaulting 2. inject the following code to main.gohookServer := mgr.GetWebhookServer()
hookServer.Register("/mutate-v1alpha1-workflow", &webhook.Admission{Handler: &webhookv1alpha1.ArgoWorkflowHandler{Client: mgr.GetClient()}}) 3. generate webhook file
|
@camilamacedo86 can you elaborate on this point? I'm trying to use kubebuilder (through operator-sdk) to scaffold some webhooks for core types, but there seems to be a lot of confusion around how to do this. I've yet to find a canonical example that just works. Edit: I hammered away on a boiled down example. From what I can tell, all scaffolding works, as well as the integration tests. It wasn't that much tweaking, but it was far from intuitive. Hopefully this repo will serve as a learning tool for this issue and for a workaround in the meantime. The commits are broken up so people can see the progression from initialization to working repo state. |
This issue is labeled with You can:
For more details on the triage process, see https://www.kubernetes.dev/docs/guide/issue-triage/ /remove-triage accepted |
/priority important-longterm |
/assign |
Any update or solution? |
I want to create a controller for an external type, ex.
core/v1.Pod
orroute.openshift.io/v1.Route
, and have kubebuilder be aware that this type is external (for commands I run aftercreate api
).Currently external types are supported, but are treated as custom types, which can cause problems with scaffolding controller files. Additionally the edge case of the "core" group, which is "" in actual GVKs, isn't handled well.
From #1772:
Regarding creating a new command: The most common use case by far (anecdotal evidence only) is creating both a controller and resource. I do sometimes see one or the other (or neither) being created to support external types, so having the choice of either or neither mode is still useful. Having a command for each mode confounds the currently straightforward workflow. Therefore I vote to leave the
create api
command as-is, except invert flag defaults totrue
.Regarding the extra flag on
create api
: Having an extra flag makes sense, since we need to know where the external types are coming from as they aren't inapi/<version>
orapis/<group>/<version>
. I like @camilamacedo86's idea of supplying a module/import path, perhaps with a more descriptive flag like--external-import
.kubebuilder create api
shouldn't be doing anygo get
stuff though; that'll be done by calling make targets. The input would also have to describe the exact import path, and--group
would have to be the full API group:We might also want to add the resource to
resources
in the config with anexternal: <boolean>
qualifier.Related: #1975 (loosely), #1772
/kind feature
The text was updated successfully, but these errors were encountered: