zalando-incubator / kopf

A Python framework to write Kubernetes operators in just few lines of code.
https://kopf.readthedocs.io
MIT License
970 stars 88 forks source link

Get the namespace value passed into the cli in startup handler #280

Open fangpenlin opened 4 years ago

fangpenlin commented 4 years ago

Expected Behavior

I guess this is more like a feature request. Now I can run the operator with --namespace argument like this

kopf run my_operator.py --namespace=default

correct me if I am wrong, but I looked into the source code, it seems like there's no way to get this namespace value. For my use case, I would like to do some initial API calls in my startup handler, like this

@kopf.on.startup()
async def startup_handler(namespace, logger, **kwargs):
    custom_api = kubernetes.client.CustomObjectsApi()
    my_crds = list_crds(custom_api, namespace)
    # ...

as you can see the namespace value is not provided, so this won't work. It's not a big deal, I can pass the namespace via other ways like environment variables. But ideally, I think it would be nice there's a global variable that I can access for this namespace value or maybe pass it to the startup handler so that developer can decide how to deal with it.

Actual Behavior

There's no way to get the namespace passed in

Steps to Reproduce the Problem

N/A

Specifications

N/A

nolar commented 4 years ago

Thanks for suggesting. Maybe namespace alone is not so special to be passed, but the whole CLI config can be packed into a single config-object, and passed to the startup/cleanup/login and maybe the regular resource handlers as one config kwarg, with config.namespace having the namespace from CLI.

Just few extra ideas to think: It could also take the existing but undocumented kopf.config tweaks and classes into it. And it can be made mutable (fully or partially), so that the startup handler could do the operator setup; or that the config settings could be modified at runtime depending on the k8s resources (their values or their amount; e.g. a thread-pool executor size).

A question to think on (conceptually): Should the settings of an operator framework be in any way mixed with the settings of a specific operator (even if the operator is based on the framework)? How is it done in the web-frameworks (Flask, Django, etc)?

eshepelyuk commented 4 years ago

Hi Any updates on this ?

Also interested in similar feature, although for different scenario. My operator is not limited to a single namespace, but it watches cluster wide events and should update the namespace where it is deployed to, ie create some pods / crd there. So, how the operator could know its own namespace ?

nolar commented 4 years ago

@eshepelyuk I would suggest to use 12-factor app-style configuration via env vars: pass a NAMESPACE (or MYOP_NAMESPACE) env var both to --namespace=$NAMESPACE and interpret it in your handlers via os.environ['NAMESPACE']. Basically, consider your operator as an application on its own.

Keep in mind: I have an intention to extend the --namespace CLI semantic soon: it will be possible to pass few namespaces, and also namespace positive and negative globs: --namespace=team-*-pr-123-* --namespace=team-app-main, and so. The "one fixed namespace" case will continue working as before as a subset of this generic namespace selection feature.

So, passing Kopf's CLI values to the handlers might be confusing and difficult to interpret. Your own operator's configs should work perfectly fine.

If needed, you can implement your own CLI for your own operator with embedded operators feature. All in all, Kopf's own CLI is as simple as this pass-through function: https://github.com/zalando-incubator/kopf/blob/0.27rc6/kopf/cli.py#L60-L88

eshepelyuk commented 4 years ago

Hi @nolar there's a confusion here,

My case is different from the origin of the issue. I don't need to get CLI parameters in handlers at all. Instead, I'd like to get a single NS where operator is deployed, only this NS - actual location of an operator pods. Basically I can achive this by retrieving oeprator deployment or pod by some labes in create handler. But I suppose - it would be useful to inject deployment object into create handler. It may be helpful for other scenarios as well.

Usually, apps (services) running in k8s doesn't need NS at all, so I consider passing NS as env var as a last resort for my case.