README: add customize logic section#20
README: add customize logic section#20hongchaodeng merged 2 commits intooperator-framework:masterfrom hongchaodeng:doc
Conversation
|
Laying out the workflow of "customization" section. |
| Func: KubeApplyFunc, | ||
| }) | ||
|
|
||
| if !obj.Spec.CreateService { |
There was a problem hiding this comment.
Create is a verb, which should not exist in a declarative config. WithService or service is better.
|
Finished. |
|
lgtm as initial pass |
|
|
||
| An operator is used to extend the kube-API and codify application domain knowledge. Operator SDK is designed to provide a way for non-Kubernetes developers to write the business logic in operators easily. | ||
|
|
||
| In the following we are customizing the operator logic so that once a new `PlayService` is created it will deploy a Memcached Deployment and (optional) Service. |
There was a problem hiding this comment.
Why play service? It seems random and informal. I would rather use example or just memcached
There was a problem hiding this comment.
Any suggestion?
use example or just memcached
The issue is we are trying to avoid duplicate naming and confusion. "example" is already used in "example.com". "memcached" is too specific for default API. Or we can add a section to change the API?
There was a problem hiding this comment.
all the default naming should be derived from user input not a fixed one. Or it won’t make any sense for anyone to even start a project with default options.
There was a problem hiding this comment.
So what are the suggestions? Can you be more specific given what we have?
There was a problem hiding this comment.
@hongchaodeng I do not have any immediate suggestion. I am just saying what we have right now does not make sense to me.
What I suggested in the google doc is that we should have a sane default not to have a random or unusable default. Having a bad default is even worse than not having a default.
A good default is what most people would adopt it without changing anything. That is why good defaults get derived from a limited number of user inputs or environments.
There was a problem hiding this comment.
A good default is what most people would adopt it without changing anything.
I agree. The current PlayService doesn't reflect good enough on memcached deployment. Let me make some changes to the workflow.
| Generate a new project: | ||
|
|
||
| ``` | ||
| operator-sdk new memcached-operator --api=cache.example.com/v1:Memcached |
There was a problem hiding this comment.
it seems to me that we should enforce the project name to be <domain name>/<operator-name>
in this example, it should be operator-sdk new cache.example.com/memcached.
the default versioning should be alpha1 which can be overwritten by flag options. similarly, other default options should be derived from the project name and can be overwritten by flag options.
There was a problem hiding this comment.
in this example, it should be operator-sdk new cache.example.com/memcached.
But that's not projects are structured. For example, we have coreos/etcd-operator. If we want to comply with this convention, it would be etcd.database.coreos.com/etcd-operator. IMHO, this would make user's life harder to manage the project directory if we couple the naming and the API.
Secondly, this is an example to explicitly show how to API group, version, kind, which are needed to start an operator project. If we have too many defaults that it is less useful for users to customize.
There was a problem hiding this comment.
i do not like ask users to provide duplicated information to start with. but if we cannot figure out good defaults, then there should be no defaults. all options should be required as what @fanminshi proposed initially.
There was a problem hiding this comment.
also in your example user should do
operator-sdk new database.coreos.com/etcd-operator
which i think includes all information we need to lay out the project initially. Basically all we need is the domain name + operator name. i do not know why we need other information.
There was a problem hiding this comment.
then there should be no defaults
I think this is the way to go. By default we should only have minimal common things. We will generate additional things like API, handlers afterwards.
There was a problem hiding this comment.
what is the reason to have separate phases?
This would be cleaner to have separate workflow to handle separate things, generating new custom resources, generate new handlers, etc. instead of coupling everything to the single "new" generating scaffolding command.
There was a problem hiding this comment.
operator-sdk new database.coreos.com/etcd-operator
Do you mean that this would generate project folder 'etcd-operator', with apigroup "database.coreos.com", and kind "etcd" by default?
There was a problem hiding this comment.
This would be cleaner to have separate workflow to handle separate things, generating new custom resources, generate new handlers, etc. instead of coupling everything to the single "new" generating scaffolding command.
why it is cleaner? it might be cleaner to the developer but may be tedious for the users. from users perspective, they probably want to have one click experience.
There was a problem hiding this comment.
Do you mean that this would generate project folder 'etcd-operator', with apigroup "database.coreos.com", and kind "etcd" by default?
yes. also version alpha by default. that is what most users would expect i guess.
There was a problem hiding this comment.
OK. I see your point now. Let me think about it.
|
Rewritten to reflect the discussion on #20 (comment). PTAL |
|
|
||
| ``` | ||
| operator-sdk new play-operator | ||
| operator-sdk new cache.example.com Memcached |
There was a problem hiding this comment.
why not cache.example.com/Memcached? it is easier to parse and more intuitive when we explain that the project name has to be the format of <domain>/<name>
There was a problem hiding this comment.
For kube API, the convention is group/version, e.g. apps/v1.
This would avoid the confusion.
We also preserve the ability to specify version later in conventional way cache.example.com/v1.
There was a problem hiding this comment.
when would a user create a new project with version v1 instead of v1alpha1?
There was a problem hiding this comment.
what i proposed is to ask user for a single project name. and we try to derive a set of sane default options from that single string.
if we do want to provide the max flexibility and do not want to abstract anything. i would perfer what @fanminshi suggested initially by asking from all options without any defaulting.
the approach you just proposed with separating the api group and CR name with a space seems unintuitive to me.
There was a problem hiding this comment.
what i proposed is to ask user for a single project name.
There is one issue -- we can't infer apigroup from the project name.
There was a problem hiding this comment.
The initial proposal is:
new <project-name> <api-group> <kind>
We basically coalesce <project-name> and <kind>. <api-group> is not something we can easily infer.
There was a problem hiding this comment.
There is one issue -- we can't infer apigroup from the project name.
why not? you ask users to put that into the project name. project name is basically an abstraction over whatever you want it to be. i already provided an example project name (cache.coreos.com/memcached). it should include everything we ever need with the new command. i mentioned a few times that it is OK to assume the version is always v1alpha1. or you can make the project name to be cache.coreos/v1/memcached. the operator name would be memcached-operator.
again, if we do not want to have the abstraction, i would prefer what @fanminshi proposed initially to require everything without any defaulting/inference or any abstraction.
i failed to see the benefits with the middle ground approach you proposed since it is kind of half done.
There was a problem hiding this comment.
@xiang90 @hasbro17 @fanminshi
Do you have any suggestion to solve the problem? I really can't think of any ways to reduce parameters.
There was a problem hiding this comment.
you ask users to put that into the project name.
What project name? memcached-operator?
Let's go back to the initial plan:
new <project-name> <api-group> <kind>
e.g.
new memcached-operator cache.example.com Memcached
There was a problem hiding this comment.
Let's define project name is the repo name.
|
After discussion, here are the conclusions:
|
|
|
||
| ``` | ||
| kubectl create -f deploy/play-operator/operator.yaml | ||
| kubectl create -f deploy/memcached-operator/operator.yaml |
There was a problem hiding this comment.
i would like to see operator-sdk up or something that will setup a local minikube cluster. but we can do that later on.
There was a problem hiding this comment.
We will discuss that tomorrow.
Ideally, a workflow like this would be helpful to users:
- Check if
$HOME/.kube/configor$KUBECONFIGexists. - If not,
minikube start - Then deploy operator.
There was a problem hiding this comment.
@xiang90 I think something like operator-sdk up is a good idea. I have seen this type of command in many web framework. we can do that later.
|
|
||
| ``` | ||
| operator-sdk new play-operator | ||
| operator-sdk new memcached-operator --apigroup=cache.example.com/v1alpha1 --kind=Memcached |
There was a problem hiding this comment.
By linux convention, flags are optional. So if we want to enforce user to input apigroup and kind, we should use input args instead.
for example,
operator-sdk new [project-name] [api-group] [kind]
|
lgtm on initial pass. we can have additional improvement on this doc later. |
|
|
||
| An operator is used to extend the kube-API and codify application domain knowledge. Operator SDK is designed to provide non-Kubernetes developers an easy way to write the business logic. | ||
|
|
||
| In the following we are adding a custom resource `Memcached`, and customizing the operator logic that creating a new Memcached CR will create a Memcached Deployment and (optional) Service. |
There was a problem hiding this comment.
In the following steps we are . . .
|
|
||
| In the following we are adding a custom resource `Memcached`, and customizing the operator logic that creating a new Memcached CR will create a Memcached Deployment and (optional) Service. | ||
|
|
||
| In `pkg/apis/cache/v1alpha1/types.go`, Add to `MemcachedSpec` a new field `WithService`: |
| bar | ||
| ``` | ||
|
|
||
| Now we have successfully to customize the event handling logic to deploy Memcached service for us. |
There was a problem hiding this comment.
successfully to customize ==> successfully customized
|
LGTM. I'll need to update the Handler code a bit once I'm done implementing the sdk Actions. |
Add jmespath to dependencies
No description provided.