A tool to help you migrate OAM CRDs from v1alpha1 to v1alpha2.
This migration tool is primarily a conversion webhook like admission webhook. This webhook
handles the ConversionReview
requests sent by the API servers, and sends back conversion
results wrapped in ConversionResponse
. The specific conversion logic can be customized by the
user.
More details see this.
In this doc we introduced all possible solutions we have thought through to do migration in general mechanism.
This tool implements the first one which aligns with upstream and provides a self-contained solution.
- crd conversion webhook
- a golang script to remove old versions from CRD
status.storedVersions
- Functions such as
Server
define how to handleConversionReview
requests and responses and generally do not need to be changed. 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.type convertFunc func(Object *unstructured.Unstructured, version string) (*unstructured.Unstructured, metav1.Status)
- The
doConversionV1
anddoConversionV1beta1
functions also need to be modified if the user uses a specific type of CR as the input/output ofconvertFunc
. Change thecr
variable type to the CR desired by the user.func doConversionV1(convertRequest *v1.ConversionRequest, convert convertFunc) *v1.ConversionResponse { var convertedObjects []runtime.RawExtension for _, obj := range convertRequest.Objects { cr := unstructured.Unstructured{} if err := cr.UnmarshalJSON(obj.Raw); err != nil { ... } klog.Info("get storage object successfully, its version:", cr.GetAPIVersion(), ", its name:", cr.GetName()) convertedCR, status := convert(&cr, convertRequest.DesiredAPIVersion) ...
ConvertAppConfig
is an implementation ofconvertFunc
, 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.func ConvertAppConfig(Object *unstructured.Unstructured, toVersion string) (*unstructured.Unstructured, metav1.Status)
- The interface defines a collection of conversion methods for the
Components
andTraits
fields in ApplicationConfiguration. Users can customize the conversion logic by implementing methods.type Converter interface { ConvertComponent(v1alpha1Component) (v1alpha2Component, v1alpha2.Component, error) ConvertTrait(v1alpha1Trait) (v1alpha2Trait, error) }
- Variable definition: Because the ApplicationConfiguration in this example is an unstructured structure, variables are defined as
interface{}
ormap[string]interface{}
for the convenience of obtaining and modifying specific fields in the nested structure.type v1alpha1Component interface{} type v1alpha2Component map[string]interface{} type v1alpha1Trait interface{} type v1alpha2Trait map[string]interface{}
- Clusters with old versions of CRD
kubectl kustomize ./crd/bases/ | kubectl apply -f - kubectl apply -f crd/appconfig_v1alpha1_example.yaml
- Because webhook is deployed in default namespace in this demo, permissions should be assigned.
kubectl apply -f crd/role-binding.yaml
- Create secret for ssl certificates
curl -sfL https://raw.githubusercontent.com/crossplane/oam-kubernetes-runtime/master/hack/ssl/ssl.sh | bash -s oam-crd-conversion default kubectl create secret generic webhook-server-cert --from-file=tls.key=./oam-crd-conversion.key --from-file=tls.crt=./oam-crd-conversion.pem
- Create CA Bundle info and inject into the CRD definition
caValue=`kubectl config view --raw --minify --flatten -o jsonpath='{.clusters[].cluster.certificate-authority-data}'` sed -i 's/${CA_BUNDLE}/'"$caValue"'/g' ./crd/patches/crd_conversion_applicationconfigurations.yaml
- Build image and deploy a deployment and a service for webhook
docker build -t example:v0.1 . kubectl apply -f deploy/webhook.yaml
- Patch new versions and conversion strategy to CRD
kubectl get crd applicationconfigurations.core.oam.dev -o yaml >> ./crd/patches/temp.yaml kubectl kustomize ./crd/patches | kubectl apply -f -
- Verify that the old and new version objects are available
# kubectl describe applicationconfigurations complete-app Name: complete-app Namespace: default Labels: <none> Annotations: API Version: core.oam.dev/v1alpha2 Kind: ApplicationConfiguration ... Traits: Trait: API Version: core.oam.dev/v1alpha2 Kind: RollOutTrait Metadata: Name: rollout Spec: Auto: true Batch Interval: 5 Batches: 2 Canary Replicas: 0 Instance Interval: 1 # kubectl describe applicationconfigurations.v1alpha1.core.oam.dev complete-app Name: complete-app Namespace: default Labels: <none> Annotations: API Version: core.oam.dev/v1alpha1 Kind: ApplicationConfiguration ... Traits: Name: rollout Properties: Name: canaryReplicas Value: 0 Name: batches Value: 2 Name: batchInterval Value: 5 Name: instanceInterval Value: 1 Name: auto Value: true
Here we use kube-storage-version-migrator as an example, you can write Go scripts instead.
- Run the storage Version migrator
git clone https://github.com/kubernetes-sigs/kube-storage-version-migrator sed -i 's/kube-system/default/g' ./Makefile make local-manifests sed -i '1,5d' ./manifests.local/namespace-rbac.yaml pushd manifests.local && kubectl apply -k ./ && popd
- Verify the migration is "SUCCEEDED"
kubectl get storageversionmigrations -o=custom-columns=NAME:.spec.resource.resource,STATUS:.status.conditions[0].type NAME STATUS ... ... applicationconfigurations SUCCEEDED ... ...
- Run the golang script that removes old versions from CRD
status.storedVersions
fieldgo run remove/remove.go updated applicationconfigurations.core.oam.dev CRD status storedVersions: [v1alpha2]
- Verify the script runs successfully
kubectl describe crd applicationconfigurations.core.oam.dev Name: applicationconfigurations.core.oam.dev Namespace: ... Stored Versions: v1alpha2 Events: <none>
- Remove the old version from the CustomResourceDefinition spec.versions list
kubectl get crd applicationconfigurations.core.oam.dev -o yaml >> ./crd/complete/temp.yaml kubectl kustomize ./crd/complete | kubectl apply -f -