Change:
} func (o *WardleServerOptions) Complete() error { <ins> // register admission plugins banflunder.Register(o.RecommendedOptions.Admission.Plugins) // add admisison plugins to the RecommendedPluginOrder o.RecommendedOptions.Admission.RecommendedPluginOrder = append(o.RecommendedOptions.Admission.RecommendedPluginOrder, "BanFlunder") </ins> return nil } func (o *WardleServerOptions) Config() (*apiserver.Config, error) { <del> // register admission plugins banflunder.Register(o.RecommendedOptions.Admission.Plugins) </del> // TODO have a "real" external address if err := o.RecommendedOptions.SecureServing.MaybeDefaultWithSelfSignedCerts("localhost", nil, []net.IP{net.ParseIP("127.0.0.1")}); err != nil { return nil, fmt.Errorf("error creating self-signed certificates: %v", err)

Discussion:
<!-- This form is for bug reports and feature requests ONLY! If you're looking for help check and the . If the matter is security related, please disclose it privately via --Is this a BUG REPORT or FEATURE REQUEST?: What happened: I made an extension apiserver based on the sample. My extension apiserver adds an admission plugin, as does the sample. But if that admission plugin is enabled from the command line then validation fails. There are two problems. For the first, note that invokes validation before --- which is where the additional admission plugin gets (see how leads to which is what gets to ). I fixed that inversion by promoting some code from to in my extension server. That exposed the other problem, which comes from . The sample apiserver does not add its admission plugin to , so this check trips. What you expected to happen: I expected to be able to use my admission plugin. How to reproduce it (as minimally and precisely as possible): Anything else we need to know?: Environment: Kubernetes version (use ): Cloud provider or hardware configuration: OS (e.g. from /etc/os-release): Kernel (e.g. ): Install tools: Others:
actually, we're facing the same problem in kube-apiserver. but currently we walkaround by explicitly registering all known builtin plugins beforehand.
we're already working on simplifying the launch-flow for servers (including plugin initialization), but it'll take some time. maybe we can a better solution for this issue after that.
You can see how I solved it, in --- at first those lines were in --- and in the additional statement at (with parameter of adjusted accordingly).
no, u don't have to walkaround like that. just registering all the built-in plugins on instantiating the option struct will be fine.
What in sample-apiserver corresponds to ?
the is the existing & possibly correct way to build a server, isn't it? the is just a generic demo, and it doesn't reveal how to extend or make use of advanced features like admission plugin.
sample-apiserver does aim to illustrate how to implement admission plugins. My complaint here is that the illustration is broken. In the kubernetes ecosystem there is a distinction between the main apiserver and extension apiservers. kubeapiserver is the one and only main apiserver; sample-apiserver is meant to be an example of an extension apiserver.

Extension apiservers are intended to support their own admission plugins.
Actually, I do not know why my network apiserver works; it should crash because the field is set in the wrong copy of the . Moving one fewer statement from to fixes that.
cc