-
Notifications
You must be signed in to change notification settings - Fork 89
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
Base migration framework #119
Conversation
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.
Thanks @ulucinar I left a few comments.
caae7a6
to
acbea16
Compare
8508801
to
c0f5204
Compare
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.
Thanks @ulucinar ! Loved how much documentation the code has! I have a couple of non-nit comments but at a high level, it looks pretty good!
ComposedTemplates(cmp v1.ComposedTemplate, convertedBase ...*v1.ComposedTemplate) error | ||
} | ||
|
||
// Source is a source for reading resource manifests |
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.
Do we really need the abstractions over source and target? AFAIK, there are two main scenarios we'd like to handle;
- Running against live Kubernetes cluster.
- Read resources from cluster and write to the filesystem, prepare a migration plan on filesystem, execute it against the cluster.
- Running against manifests stored in a Git repo, i.e. GitOps, hence filesystem.
- The files are already on the filesystem, prepare a migration plan on filesystem, skip the execution since the files will be committed.
So, it feels like if we have a seperate utility to get resources from cluster to filesystem that can be turned off by a flag, then the rest of the steps are already normalized to work on the filesystem if I'm not missing something.
// Example: resources/a.yaml:resources/b.yaml | ||
Parents string | ||
// IsComposite set if the object belongs to a Composite type | ||
IsComposite bool |
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.
nit: Category string
, which is used in CRDs as well, as single field could help here to classify.
// together with the associated Metadata. | ||
type UnstructuredWithMetadata struct { | ||
Object unstructured.Unstructured | ||
Metadata Metadata |
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.
I think Metadata
word is overloaded in this context. Can we have another name? Descriptor
maybe?
pg.Plan.Spec.Steps[stepDeleteOldManaged].Name = "delete-old-managed" | ||
pg.Plan.Spec.Steps[stepDeleteOldManaged].Type = StepTypeDelete | ||
deletePolicy := FinalizerPolicyRemove | ||
pg.Plan.Spec.Steps[stepDeleteOldManaged].Delete = &DeleteStep{ |
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.
I think we should let the controller do a graceful orphaned deletion so that we stay on the normal path of execution. For example, unpublishing connection details is something done in orphan deletion where we'd not get to have.
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.
Will check this in a future iteration after testing the behavior. Thank you!
pkg/migration/plan_generator.go
Outdated
annot = make(map[string]string) | ||
} | ||
annot[meta.AnnotationKeyReconciliationPaused] = "true" | ||
u.SetAnnotations(annot) |
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.
nit: There is meta.AddAnnotations
function in runtime that would help here.
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.
Done.
if err := pg.target.Put(*u); err != nil { | ||
return errors.Wrap(err, errResourceOutput) | ||
} | ||
return nil |
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.
if err := pg.target.Put(*u); err != nil { | |
return errors.Wrap(err, errResourceOutput) | |
} | |
return nil | |
return errors.Wrap(pg.target.Put(*u), errResourceOutput) |
nit
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.
Done.
} | ||
} | ||
default: | ||
if o.Metadata.IsComposite { |
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.
nit: handling these IsComposite
and IsClaim
as cases in switch
could make it easier to read.
pkg/migration/converter.go
Outdated
// unstructured.Unstructured. Before the converted object is | ||
// returned, it's sanitized by removing certain fields | ||
// (like status, metadata.creationTimestamp). | ||
func ToUnstructured(mg any) unstructured.Unstructured { |
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.
Can we name this something like ToSanitizedUnstructured
or ToSanitized
? It could be misleading otherwise since there is a known ToUnstructured
method in upstream libraries.
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.
Done.
|
||
var ( | ||
// the default Converter registry | ||
registry Registry = make(map[schema.GroupVersionKind]Converter) |
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.
nit: I'd lean towards leaving it to the consumer of this package to initialize and maintain their Registry
object instead of us providing a global map unless we have to.
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.
Makes sense. Planning to address in the next iteration.
Path string | ||
// colon separated list of parent `Path`s for fan-ins and fan-outs | ||
// Example: resources/a.yaml:resources/b.yaml | ||
Parents string |
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.
I see this field isn't used anywhere. Is it a leftover?
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.
This field is to be employed by the source and target implementations.
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.
Most of my comments were non-blocking, feel free to go ahead! Thanks @ulucinar !
Signed-off-by: Alper Rifat Ulucinar <[email protected]>
Signed-off-by: Alper Rifat Ulucinar <[email protected]>
2b26008
to
81b18ac
Compare
d1b3cc2
to
af81b4a
Compare
Signed-off-by: Alper Rifat Ulucinar <[email protected]>
af81b4a
to
81c9dbe
Compare
Description of your changes
Fixes https://github.com/upbound/team-extensions/issues/29
This PR introduces the base framework for migrating from community providers to official providers.
I have:
make reviewable
to ensure this PR is ready for review.backport release-x.y
labels to auto-backport this PR if necessary.How has this code been tested
Manually tested using the implemented sample converter and the following manifests:
And the following sample converter for community provider VPC resources (under
pkg/migration/converters/vpc_converter.go
):The converted resources are as follows: