kustomize icon indicating copy to clipboard operation
kustomize copied to clipboard

convert resources to ResourceGenerator

Open koba1t opened this issue 2 years ago • 17 comments

https://github.com/kubernetes-sigs/kustomize/issues/4402

koba1t avatar Jun 28 '23 19:06 koba1t

Skipping CI for Draft Pull Request. If you want CI signal for your change, please convert it to an actual PR. You can still manually trigger a test run with /test all

k8s-ci-robot avatar Jun 28 '23 19:06 k8s-ci-robot

I have a problem with the import cycle not allowed error. The accumurateTarget function is processing for kustomization.yaml, and I think ResourceGenerator needs exec this function due we need to process another kustomozation.yaml in the nested subdirectories. But the target package contains the accumurateTarget function and imports the builtin package, which contains every generator code. That means if we want to call accumurateTarget in any generator plugins, that happens to cycle import for go codes and can't compile.

So Do you have any idea to fix this? I need your help resolving this code structure problem.

koba1t avatar Jul 09 '23 19:07 koba1t

This PR has multiple commits, and the default merge method is: merge. You can request commits to be squashed using the label: tide/merge-method-squash

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

k8s-ci-robot avatar Jul 11 '23 14:07 k8s-ci-robot

@koba1t If I understand correctly, the problem is that when you create a generator for resources, the resourceGenerator is in builtins, and needs to call accumulateTarget which is in target. But to process the kustomization file properly, accumulateTarget in target needs to call the generators in builtins, resulting in the import cycle.

We may have already discussed this, but did you try moving all the files from target (all of these files) to the builtins folder, so that it's all in the same package, to avoid the dependencies? I'm not yet sure if this is the right way to go, but I would like to know if this could potentially resolve the issue (and also help to confirm my understanding of the problem).

natasha41575 avatar Jul 21 '23 15:07 natasha41575

I resolved to import cycle problem with adding member variable contain pointer of kt for PluginHelperstruct. But I can't decide whether this is the right approach for resolving this problem.

If you have any ideas, please let me know.

koba1t avatar Aug 30 '23 19:08 koba1t

@natasha41575

I have a problem with fields that affect out of the resources directory scope. I think the effect of vars and crd fields are not limited on once accumulateTarget, but any Generator needs return ResMap type result without ResAccumulator that decided by interface and ResourceGenerator return ResMap. ResAccumulator can contain these fields' data but the ResMap struct looks like a simple struct and I think I can't store data of these fields

So, If we need to keep current behavior, we may need some other keep of these fields. Do you have any good ideas?

koba1t avatar Aug 30 '23 20:08 koba1t

@natasha41575

I have a problem with fields that affect out of the resources directory scope. I think the effect of vars and crd fields are not limited on once accumulateTarget, but any Generator needs return ResMap type result without ResAccumulator that decided by interface and ResourceGenerator return ResMap. ResAccumulator can contain these fields' data but the ResMap struct looks like a simple struct and I think I can't store data of these fields

So, If we need to keep current behavior, we may need some other keep of these fields. Do you have any good ideas?

If I understand the problem correctly, then I can think of a couple suggestions

  1. I think it is OK to add crds and vars to ResMap if that appears to be the cleanest solution. To do this, I think you would need to add methods to the ResMap interface to get the crds and vars, and store them in the ResWrangler.

  2. You could maybe change the generators interface to return a type ResAccumulator instead of ResMap. Then you can add the additional fields to ResAccumulator. For other generators that are not ResourceGenerator, we can leave all the other fields besides ResMap empty if needed. But I think to do this, we will need to take ResAccumulator out of api/internal, so that users can still built their own custom generators if they want to. I think we should try to avoid this though. Edited to add: If we change the generators interface, we might also have to change the transformers/validators interfaces and double check that KRM functions still work, and this might be a breaking change for legacy style functions, so maybe this solution isn't actually feasible.

  3. We can define a new wrapper around ResMap, e.g. ResMapWithGlobalData that contains a ResMap and the crds and vars data.

  4. Another potential option (though I'm not sure if this one will solve your issue) - we do already have a wrapper called GeneratorWithProperties that we use to store origin information. It is used to configure and run the generators: https://github.com/kubernetes-sigs/kustomize/blob/f81765b96ecc09f6f822fa5093e7f8b2f5a9713c/api/internal/target/kusttarget.go#L268. I'm curious if it might be possible to add the crd/vars data there, and have runGenerators return them when applicable.

  5. If it helps in conjunction with any of the other options, we can potentially run resourceGenerator separately from the other generators, e.g. have a separate configureResourceGenerator - separate from the configureBuiltinGenerator. This is a bit hacky though so we should try to avoid this if possible.

Of these options, I'm hoping that (3) or (4) will be feasible. (1) is okay too. (2) and (5) we should try to avoid if we can, but we can consider them if the other options aren't possible. I am also open to other solutions if you can come up with some better ideas.

natasha41575 avatar Sep 08 '23 17:09 natasha41575

@koba1t I edited my comment for (2) above - I think changing the Generators interface is actually not feasible and will have a lot of consequences, so let's try to avoid that one.

natasha41575 avatar Sep 15 '23 18:09 natasha41575

Thanks for thinking of a solution and explaining it so clearly! I'm first testing if (3) or (4) works well!

koba1t avatar Sep 16 '23 11:09 koba1t

Thanks for thinking of a solution and explaining it so clearly! I'm first testing if (3) or (4) works well!

Hi everyone, just a little idea of mine. How about adding crds and vars as optional field and applying Builder pattern on ResMap interface or resWrangler struct? I think putting the function on resWrangler is more appropriate since it has higher point of view on the kustomization.

func (r ResMap) withProperties(crds []kt.Crds, vars []types.Var ) ResMap {
     r.crds = crds
     r.vars = vars
     return r
}

We can call it from Factory

m, err := newResMapFromResourceSlice(ress).withProperties(crds,vars)

Alternatively, instead of adding individual optional fields like crds and vars we can make it more scalable by bundling them under an umbrella field like properties and use variadic arguments, e.g. withProperties(properties ...properties). Let me know if I don't get it correctly and I apologise if I misinterpreted the input type 🙇 .

Ideally speaking, we should separate CRDs and Vars as its own maps and make Generators return bunch of maps :)

Example implementation: https://medium.com/@reetas/clean-ways-of-adding-new-optional-fields-to-a-golang-struct-99ae2fe9719d

antoooks avatar Sep 27 '23 09:09 antoooks

Thanks @antoooks! I think that's an interesting idea as well. @koba1t please feel free to explore that potential solution as well. It looks similar to my (3) above but I think @antoooks's idea is more elegant if it works.

natasha41575 avatar Oct 20 '23 15:10 natasha41575

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: koba1t

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment Approvers can cancel approval by writing /approve cancel in a comment

k8s-ci-robot avatar Nov 29 '23 21:11 k8s-ci-robot

PR needs rebase.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

k8s-ci-robot avatar Feb 25 '24 20:02 k8s-ci-robot