devconsole-operator icon indicating copy to clipboard operation
devconsole-operator copied to clipboard

Use Pure Go for creating kube resource v/s templatize'd yamls

Open sbose78 opened this issue 5 years ago • 8 comments

Do we want to create a kube object as

_, err = c.serviceCatalogClient.ServiceInstances(c.Namespace).Create(
		&scv1beta1.ServiceInstance{
			TypeMeta: metav1.TypeMeta{
				Kind:       "ServiceInstance",
				APIVersion: "servicecatalog.k8s.io/v1beta1",
			},
			ObjectMeta: metav1.ObjectMeta{
				Name:      serviceName,
				Namespace: c.Namespace,
				Labels:    labels,
			},
			Spec: scv1beta1.ServiceInstanceSpec{
				PlanReference: scv1beta1.PlanReference{
					ClusterServiceClassExternalName: serviceType,
					ClusterServicePlanExternalName:  servicePlan,
				},
				Parameters: serviceInstanceParameters,
			},
		})

in our code, or do we want to use templatized yaml files to generate objects ?

sbose78 avatar Mar 04 '19 15:03 sbose78

Do we want to create a kube object in our code, or do we want to use templatized yaml files to generate objects?

How would this templatization work? Will we be using https://github.com/kubernetes-sigs/kustomize? If so, I would vote in favour of using pure go to create kube objects.

Using https://github.com/kubernetes-sigs/kustomize to create yamls would add unnecessary complexity to the system. Every time a yaml has to be updated, we'll have to update the template and regenerate the yaml files. This could make sense if we have too many resources running in the system where manually maintaining the yamls would be difficult. In our case, I think there would be only a few resources and we can manually manage those (via go code).

Also, if we're using templatized yamls, we'll have to add (maybe embed) the generated yamls file in the operator binary. Would a custom controller be able to access the yaml? I don't know. We might have to add some workarounds in the controller to read the yaml file and then apply those.

jarifibrahim avatar Mar 04 '19 16:03 jarifibrahim

I think that @sbose78 refers to go template approach which has been implemented in our snowdrop component operator [1] where we use as top level object a Component Type that we pass as object to go template during merging process

  • Example of template for a DeploymentConfig : https://github.com/snowdrop/component-operator/blob/master/pkg/util/template/tmpl/innerloop/deploymentconfig
  • Template are created as FS bytes using make assets: https://github.com/snowdrop/component-operator/blob/master/pkg/util/template/assets_vfsdata.go#L37-L43
  • Templates are loaded during init into a map : https://github.com/snowdrop/component-operator/blob/master/pkg/util/template/template.go#L40-L81

Pros : Less code to write to create the gvk as they are coded into a template, more readable, easy to maintain, can be documented / versioned for the release Cons: Assets must be regenerated when template or objects to be merged change

[1] https://github.com/snowdrop/component-operator

cmoulliard avatar Mar 04 '19 17:03 cmoulliard

My 2 cents: I favor Go even though it is slightly longer to write. Chances are that if it compiles it runs (ducking), whereas with any YAML you move this chance to runtime. And if the decision is runtime vs. compile-time I always want to minimize risk at compile time rather than runtime.

kwk avatar Mar 05 '19 07:03 kwk

If the test cases are well defined/designed, then you will not at all suffer from this compile vs runtime risk. What I like a lot with a template or file is that not only it simplifies the readability of the resource to be created but it also offers a better way to manage the versions of the resources created by the operator.

One of the problem that we and I have discovered many times is that when I upgrade the API of by example K8s ServiceCatalog, then K8s controller runtime of api machinary are not working anymore excepted if migrate to a more recent version of k8s api (e.g 1.12 or 1.13)...

By adopting such templates, you will not suffer anymore about this issue as your reference is the API published for a specific version of the doc. Example for Buildconfig v1 : https://docs.okd.io/3.11/rest_api/apis-build.openshift.io/v1.BuildConfig.html#object-schema

cmoulliard avatar Mar 05 '19 09:03 cmoulliard

One of the problem that we and I have discovered many times is that when I upgrade the API of by example K8s ServiceCatalog, then K8s controller runtime of api machinary are not working anymore excepted if migrate to a more recent version of k8s api (e.g 1.12 or 1.13)...

@cmoulliard are you saying that code like the one @sbose78 wrote in the description of this issue can go out of date more quickly than a YAML file? If that is the case, then why do we even have an API?

kwk avatar Mar 05 '19 09:03 kwk

go out of date more quickly than a YAML file?

No. What I'm saying is that maintaining go deps is more complex than having a yaml template file designed for a qualified API + Version

cmoulliard avatar Mar 05 '19 11:03 cmoulliard

All valid points, the more I look into templatized resource creation (trying to finish WIP PR), the more I wonder if plain go struct wouldn't be easier. :) Let's me do another PR so we can compare.

corinnekrych avatar Mar 05 '19 17:03 corinnekrych

Here are the PR:

  • with template (not completed yet) https://github.com/redhat-developer/devopsconsole-operator/pull/10
  • with go struct https://github.com/redhat-developer/devopsconsole-operator/pull/13

corinnekrych avatar Mar 05 '19 19:03 corinnekrych