-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementation of parent and plugin overriding #98
Conversation
Going over this PR I noticed something that for some reason I didn't notice before. The current design looks quite weird, and it is not how Strategic Merge Patch works in Kubernetes. More in my comment at #25 (comment) |
d951c43
to
42182e5
Compare
@kadel I implemented the agreement we found (summarized here ) in the PR, and updated the PR description to add details about the merging side of things (addition of elements that are not present in parents or plugins). |
cc @ranakan19 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally LGTM, with a few minor comments/nitpicks. I'll add a commit to resolve those for simplicity.
Signed-off-by: David Festal <[email protected]>
Signed-off-by: David Festal <[email protected]>
... in the future these definitions could be generated automatically from the api source code. Signed-off-by: David Festal <[email protected]>
Signed-off-by: David Festal <[email protected]>
Signed-off-by: David Festal <[email protected]>
The test yaml files provide useful hints abot how the overriding works according to strategic merge patch rules Signed-off-by: David Festal <[email protected]>
... and enhance markdown support to support code blocks. Signed-off-by: David Festal <[email protected]>
`targetPort` in `Kubernetes`-like components Signed-off-by: David Festal <[email protected]>
Signed-off-by: David Festal <[email protected]>
Signed-off-by: David Festal <[email protected]>
Signed-off-by: David Festal <[email protected]>
Signed-off-by: David Festal <[email protected]>
Signed-off-by: David Festal <[email protected]>
Signed-off-by: David Festal <[email protected]>
Signed-off-by: David Festal <[email protected]>
... And add new elements only in the main devfile body. Signed-off-by: David Festal <[email protected]>
Signed-off-by: David Festal <[email protected]>
Signed-off-by: David Festal <[email protected]>
Signed-off-by: Angel Misevski <[email protected]>
Signed-off-by: Angel Misevski <[email protected]>
00b1c64
to
13fbbc9
Compare
I had to rebase on master as there was a conflict. Commit 13fbbc9 resolves the minor comments from my review. |
Signed-off-by: Angel Misevski <[email protected]>
Signed-off-by: Angel Misevski <[email protected]>
19f6698
to
41b7264
Compare
Thanks @amisevsk for this deep review and very-valuable fixes. |
What does this PR do?
This PR implements the parent or plugin overriding.
The overriding of parent devfile or devfile plugins is implemented using the Strategic merge patch K8S library.
Implementation entry points;
The implementation is available for import in the
pkg/utils/overriding
package.Available methods are:
OverrideDevWorkspaceTemplateSpec()
to work with GO structs directlyOverrideDevWorkspaceTemplateSpecBytes
to work withjson
oryaml
content.In both case the result is a
DevWorkspaceTemplateSpecContent
Go struct that corresponds to the code content of a devfile 2.0 (without the top-levelapiVersion
andmetadata
fields).Note that one can only override an existing element of a parent or a plugin.
If a new element is added, it should be added in the main (child) devfile body. And then simple merging of top-level lists is done between the main devfile body, the flattened parent and the flattened plugins. If the key (name of ID) of a element is found several times in the merge, an error is thrown.
The corresponding methods are:
MergeDevWorkspaceTemplateSpec()
to work with GO structs directlyMergeDevWorkspaceTemplateSpecBytes
to work withjson
oryaml
content.In both case the result is a
DevWorkspaceTemplateSpecContent
Go struct that corresponds to the code content of a devfile 2.0 (without the top-levelapiVersion
andmetadata
fields).Examples of use:
YAML examples:
YAML example files are provided and used in GO tests.
Overriding
Overriding examples can be found in the following
test-fixtures/patches
folder: each sub-folder contains 3 Yaml files:original.yaml
: the original Yaml that should be overriddenpatch.yaml
: the Yaml patch that should be used to override the original fileresult.yaml
: the expected result of the overriding, which is the result of applying strategic merge patch on the original file.Merging
Merging examples can be found in the following
test-fixtures/merges
folder: each sub-folder contains up to 4 Yaml files:main.yaml
: the Yaml of the main (child) devfile body contentparent.yaml
: the Yaml of a flattened parent referenced by the main devfileplugin.yaml
: the Yaml a flattened plugin referenced by the main devfileresult.yaml
: the expected result of the merging of all those devfile contents.When opened in VSCode or
Hosted Che
, all these example files are validated with appropriate and up-to-date schemas. So they benefit from YAML language services such as completion and doc hovers.Contributions are welcomed in the future to further complete the tests (and at the same time documentation) of overriding rules.
Noteworthy (and possibly breaking) changes
Events
:Events
structure, theDevWorkspaceTemplateSpecContent
struct contains a pointer to anEvents
struct.Events
object is created although noevents
field is present in the parsedjson
oryaml
.Implementation details
Keys
Currently in the existing model, for some top-level lists (
components
,commands
), the keys of elements are not directly in the objects stored in the list, but one level lower:instead of
Furthermore for some components as
plugin
s, the key of a plugin in the list of components may be calculated, and may depend on a number of fields (id
andregistryUrl
for example).Thus a
Keyed
interface is defined and implemented for commands, components and component overrides, and it is then used to setup fixed keys in thecommands
andcomponents
lists of both the original object and the patch object during overriding.Union normalizing
In the GO API, some model types are defined as Kubernetes unions with discriminators.
The API
Union
interface defines helpers to manage correctly manage those unions, especially maintaining the fact that values in a union are mutually-exclusive.This union management logic is then used in the overriding implementation, but is also available in a dedicated
pkg/utils/unions
package that allows managing all the unions embedded in a wider object.What issues does this PR fix or reference?
This PR references issue #91
Is your PR tested? Consider putting some instruction how to test your changes
The overriding logic implemented in this PR has associated tests