{"id":18754730,"url":"https://github.com/oam-dev/oam-crd-migration","last_synced_at":"2025-07-23T14:07:44.804Z","repository":{"id":56256533,"uuid":"290650786","full_name":"oam-dev/oam-crd-migration","owner":"oam-dev","description":"A tool to help you migrate OAM CRDs from v1alpha1 to v1alpha2","archived":false,"fork":false,"pushed_at":"2020-11-18T07:06:15.000Z","size":304,"stargazers_count":7,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-13T01:11:26.357Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oam-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-08-27T02:08:15.000Z","updated_at":"2021-10-09T07:40:29.000Z","dependencies_parsed_at":"2022-08-15T15:31:30.414Z","dependency_job_id":null,"html_url":"https://github.com/oam-dev/oam-crd-migration","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/oam-dev/oam-crd-migration","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oam-dev%2Foam-crd-migration","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oam-dev%2Foam-crd-migration/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oam-dev%2Foam-crd-migration/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oam-dev%2Foam-crd-migration/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oam-dev","download_url":"https://codeload.github.com/oam-dev/oam-crd-migration/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oam-dev%2Foam-crd-migration/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266691580,"owners_count":23969182,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T17:29:50.751Z","updated_at":"2025-07-23T14:07:44.763Z","avatar_url":"https://github.com/oam-dev.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# oam-crd-migration\n\nA tool to help you migrate OAM CRDs from v1alpha1 to v1alpha2.\n\nThis migration tool is primarily a conversion webhook like admission webhook. This webhook\nhandles the `ConversionReview` requests sent by the API servers, and sends back conversion\nresults wrapped in `ConversionResponse` . The specific conversion logic can be customized by the\nuser.\n\nMore details see [this](https://github.com/crossplane/oam-kubernetes-runtime/issues/108).\n\n# Migration Solutions\n\nIn [this doc](docs/migration_solutions.md) we introduced all possible solutions we have thought through to do migration in general mechanism.\n\nThis tool implements the first one which aligns with upstream and provides a self-contained solution.\n\n# What does it include?\n- [x] [crd conversion webhook](https://github.com/kubernetes/kubernetes/tree/master/test/images/agnhost)\n- [x] [a golang script](https://github.com/elastic/cloud-on-k8s/issues/2196) to remove old versions from CRD `status.storedVersions`\n\n# For developers\n[converter/framework.go:](converter/framework.go)\n- Functions such as `Server` define how to handle `ConversionReview` requests and responses and generally do not need to be changed.\n- `convertFunc` is the user defined function for any conversion. The code in this file is a template that can be use for any CR conversion given this function. Or users can customize the input and output to be a specific type of CR.\n    ```\n    type convertFunc func(Object *unstructured.Unstructured, version string) (*unstructured.Unstructured, metav1.Status)\n    ```\n- The `doConversionV1` and `doConversionV1beta1` functions also need to be modified if the user uses a specific type of CR as the input/output of `convertFunc` . Change the `cr` variable type to the CR desired by the user.\n    ```\n    func doConversionV1(convertRequest *v1.ConversionRequest, convert convertFunc) *v1.ConversionResponse {\n        var convertedObjects []runtime.RawExtension\n        for _, obj := range convertRequest.Objects {\n            cr := unstructured.Unstructured{}\n            if err := cr.UnmarshalJSON(obj.Raw); err != nil {\n                ...\n            }\n            klog.Info(\"get storage object successfully, its version:\", cr.GetAPIVersion(), \", its name:\", cr.GetName())\n            convertedCR, status := convert(\u0026cr, convertRequest.DesiredAPIVersion)\n        ...\n    ```\n[converter/converter.go:](converter/converter.go)\n- `ConvertAppConfig` is an implementation of `convertFunc` , and the specific conversion logic is a modification of unstructured nested structure, replacing the old field description of v1alpha1 with the new field description of v1alpha2.\n    ```\n    func ConvertAppConfig(Object *unstructured.Unstructured, toVersion string) (*unstructured.Unstructured, metav1.Status)\n    ```\n    \n[converter/plugin.go:](converter/plugin.go)\n- The interface defines a collection of conversion methods for the `Components` and `Traits` fields in ApplicationConfiguration. Users can customize the conversion logic by implementing methods.\n    ```\n    type Converter interface {\n        ConvertComponent(v1alpha1Component) (v1alpha2Component, v1alpha2.Component, error)\n        ConvertTrait(v1alpha1Trait) (v1alpha2Trait, error)\n    }\n    ```\n- Variable definition: Because the ApplicationConfiguration in this example is an unstructured structure, variables are defined as `interface{}` or `map[string]interface{}` for the convenience of obtaining and modifying specific fields in the nested structure.\n    ```\n    type v1alpha1Component interface{}\n    \n    type v1alpha2Component map[string]interface{}\n    \n    type v1alpha1Trait interface{}\n    \n    type v1alpha2Trait map[string]interface{}\n    ```\n\n# User guide for appconfig examples\n## Pre-requisites\n- Clusters with old versions of CRD\n    ```\n    kubectl kustomize ./crd/bases/ | kubectl apply -f -\n    \n    kubectl apply -f crd/appconfig_v1alpha1_example.yaml\n    ```\n- Because webhook is deployed in default namespace in this demo, permissions should be assigned.\n    ```\n    kubectl apply -f crd/role-binding.yaml\n    ```\n## The conversion process\n- Create secret for ssl certificates\n    ```\n    curl -sfL https://raw.githubusercontent.com/crossplane/oam-kubernetes-runtime/master/hack/ssl/ssl.sh | bash -s oam-crd-conversion default\n    \n    kubectl create secret generic webhook-server-cert --from-file=tls.key=./oam-crd-conversion.key --from-file=tls.crt=./oam-crd-conversion.pem\n    ```\n- Create CA Bundle info and inject into the CRD definition\n    ```\n    caValue=`kubectl config view --raw --minify --flatten -o jsonpath='{.clusters[].cluster.certificate-authority-data}'`\n    \n    sed -i 's/${CA_BUNDLE}/'\"$caValue\"'/g' ./crd/patches/crd_conversion_applicationconfigurations.yaml\n    ```\n- Build image and deploy a deployment and a service for webhook\n    ```\n    docker build -t example:v0.1 .\n\n    kubectl apply -f deploy/webhook.yaml\n    ```\n- Patch new versions and conversion strategy to CRD\n    ```\n    kubectl get crd applicationconfigurations.core.oam.dev -o yaml \u003e\u003e ./crd/patches/temp.yaml\n  \n    kubectl kustomize ./crd/patches | kubectl apply -f -\n    ```\n- Verify that the old and new version objects are available\n    ```\n    # kubectl describe applicationconfigurations complete-app\n    \n    Name:         complete-app\n    Namespace:    default\n    Labels:       \u003cnone\u003e\n    Annotations:  API Version:  core.oam.dev/v1alpha2\n    Kind:         ApplicationConfiguration\n    ...\n      Traits:\n        Trait:\n          API Version:  core.oam.dev/v1alpha2\n          Kind:         RollOutTrait\n          Metadata:\n            Name:  rollout\n          Spec:\n            Auto:               true\n            Batch Interval:     5\n            Batches:            2\n            Canary Replicas:    0\n            Instance Interval:  1\n    \n    # kubectl describe applicationconfigurations.v1alpha1.core.oam.dev complete-app\n    \n    Name:         complete-app\n    Namespace:    default\n    Labels:       \u003cnone\u003e\n    Annotations:  API Version:  core.oam.dev/v1alpha1\n    Kind:         ApplicationConfiguration\n    ...\n      Traits:\n        Name:  rollout\n        Properties:\n          Name:   canaryReplicas\n          Value:  0\n          Name:   batches\n          Value:  2\n          Name:   batchInterval\n          Value:  5\n          Name:   instanceInterval\n          Value:  1\n          Name:   auto\n          Value:  true\n    ```\n## Update existing objects\nHere we use kube-storage-version-migrator as an example, you can write Go scripts instead.\n- Run the storage Version migrator\n    ```\n    git clone https://github.com/kubernetes-sigs/kube-storage-version-migrator\n  \n    sed -i 's/kube-system/default/g' ./Makefile\n  \n    make local-manifests\n  \n    sed -i '1,5d' ./manifests.local/namespace-rbac.yaml\n  \n    pushd manifests.local \u0026\u0026 kubectl apply -k ./ \u0026\u0026 popd\n    ```\n- Verify the migration is \"SUCCEEDED\"\n    ```\n    kubectl get storageversionmigrations -o=custom-columns=NAME:.spec.resource.resource,STATUS:.status.conditions[0].type\n  \n    NAME                       STATUS\n    ...                        ...\n    applicationconfigurations  SUCCEEDED\n    ...                        ...\n    ```\n## Remove old versions\n- Run the golang script that removes old versions from CRD `status.storedVersions` field\n    ```\n    go run remove/remove.go\n  \n    updated applicationconfigurations.core.oam.dev CRD status storedVersions: [v1alpha2]\n    ```\n- Verify the script runs successfully\n    ```\n    kubectl describe crd applicationconfigurations.core.oam.dev\n  \n    Name:         applicationconfigurations.core.oam.dev\n    Namespace:    \n    ...\n      Stored Versions:\n        v1alpha2\n    Events:  \u003cnone\u003e\n    ```\n- Remove the old version from the CustomResourceDefinition spec.versions list\n    ```\n    kubectl get crd applicationconfigurations.core.oam.dev -o yaml \u003e\u003e ./crd/complete/temp.yaml\n  \n    kubectl kustomize ./crd/complete | kubectl apply -f -\n    ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foam-dev%2Foam-crd-migration","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foam-dev%2Foam-crd-migration","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foam-dev%2Foam-crd-migration/lists"}