Files
open-cluster-management/pkg/addon/webhook/v1beta1/managedclusteraddon_conversion_test.go
Qing Hao c516beffa6
Some checks failed
Post / images (amd64, addon-manager) (push) Failing after 46s
Post / images (amd64, placement) (push) Failing after 41s
Post / images (amd64, registration-operator) (push) Failing after 39s
Post / images (amd64, work) (push) Failing after 42s
Post / images (arm64, addon-manager) (push) Failing after 39s
Post / images (arm64, placement) (push) Failing after 39s
Post / images (arm64, registration) (push) Failing after 40s
Post / images (arm64, registration-operator) (push) Failing after 42s
Post / images (arm64, work) (push) Failing after 39s
Post / images (amd64, registration) (push) Failing after 7m46s
Post / image manifest (addon-manager) (push) Has been skipped
Post / image manifest (placement) (push) Has been skipped
Post / image manifest (registration) (push) Has been skipped
Post / image manifest (registration-operator) (push) Has been skipped
Post / image manifest (work) (push) Has been skipped
Post / trigger clusteradm e2e (push) Has been skipped
Post / coverage (push) Failing after 14m33s
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1m25s
Close stale issues and PRs / stale (push) Successful in 46s
Add addon conversion webhook for v1alpha1/v1beta1 API migration (#1289)
* Add addon conversion webhook for v1alpha1/v1beta1 API migration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Qing Hao <qhao@redhat.com>

* Fix GroupVersion compatibility issues after API dependency update

This commit fixes compilation and test errors introduced by updating
the API dependency to use native conversion functions from PR #411.

Changes include:

1. Fix GroupVersion type mismatches across the codebase:
   - Updated OwnerReference creation to use schema.GroupVersion
   - Fixed webhook scheme registration to use proper GroupVersion type
   - Applied fixes to addon, placement, migration, work, and registration controllers

2. Enhance addon conversion webhook:
   - Use native API conversion functions from addon/v1beta1/conversion.go
   - Fix InstallNamespace annotation key to match expected format
   - Add custom logic to populate deprecated ConfigReferent field in ConfigReferences
   - Properly preserve annotations during v1alpha1 <-> v1beta1 conversion

3. Remove duplicate conversion code:
   - Deleted pkg/addon/webhook/conversion/ directory (~500 lines)
   - Now using native conversion functions from the API repository

4. Patch vendored addon-framework:
   - Fixed GroupVersion errors in agentdeploy utils

All unit tests pass successfully (97 packages, 0 failures).

Signed-off-by: Qing Hao <qhao@redhat.com>

---------

Signed-off-by: Qing Hao <qhao@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-24 08:26:35 +00:00

373 lines
11 KiB
Go

// Copyright Contributors to the Open Cluster Management project
package v1beta1
import (
"testing"
"github.com/google/go-cmp/cmp"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1"
addonv1beta1 "open-cluster-management.io/api/addon/v1beta1"
internalv1alpha1 "open-cluster-management.io/ocm/pkg/addon/webhook/v1alpha1"
)
func TestManagedClusterAddOnConvertTo(t *testing.T) {
cases := []struct {
name string
src *ManagedClusterAddOn
expected *internalv1alpha1.ManagedClusterAddOn
}{
{
name: "complete conversion with all fields",
src: &ManagedClusterAddOn{
ManagedClusterAddOn: addonv1beta1.ManagedClusterAddOn{
ObjectMeta: metav1.ObjectMeta{
Name: "test-addon",
Namespace: "cluster1",
Annotations: map[string]string{
"addon.open-cluster-management.io/v1alpha1-install-namespace": "test-namespace",
},
},
Spec: addonv1beta1.ManagedClusterAddOnSpec{
Configs: []addonv1beta1.AddOnConfig{
{
ConfigGroupResource: addonv1beta1.ConfigGroupResource{
Group: "addon.open-cluster-management.io",
Resource: "addondeploymentconfigs",
},
ConfigReferent: addonv1beta1.ConfigReferent{
Name: "config1",
Namespace: "default",
},
},
},
},
Status: addonv1beta1.ManagedClusterAddOnStatus{
Namespace: "open-cluster-management-agent-addon",
Registrations: []addonv1beta1.RegistrationConfig{
{
Type: addonv1beta1.KubeClient,
KubeClient: &addonv1beta1.KubeClientConfig{
Subject: addonv1beta1.KubeClientSubject{
BaseSubject: addonv1beta1.BaseSubject{
User: "system:addon:test",
},
},
},
},
},
ConfigReferences: []addonv1beta1.ConfigReference{
{
ConfigGroupResource: addonv1beta1.ConfigGroupResource{
Group: "addon.open-cluster-management.io",
Resource: "addondeploymentconfigs",
},
DesiredConfig: &addonv1beta1.ConfigSpecHash{
ConfigReferent: addonv1beta1.ConfigReferent{
Name: "config1",
Namespace: "default",
},
SpecHash: "hash123",
},
},
},
SupportedConfigs: []addonv1beta1.ConfigGroupResource{
{
Group: "addon.open-cluster-management.io",
Resource: "addondeploymentconfigs",
},
},
RelatedObjects: []addonv1beta1.ObjectReference{
{
Group: "apps",
Resource: "deployments",
Name: "test-deployment",
},
},
AddOnMeta: addonv1beta1.AddOnMeta{
DisplayName: "Test AddOn",
Description: "Test description",
},
HealthCheck: addonv1beta1.HealthCheck{
Mode: addonv1beta1.HealthCheckModeCustomized,
},
},
},
},
expected: &internalv1alpha1.ManagedClusterAddOn{
ManagedClusterAddOn: addonv1alpha1.ManagedClusterAddOn{
TypeMeta: metav1.TypeMeta{
Kind: "ManagedClusterAddOn",
APIVersion: "addon.open-cluster-management.io/v1alpha1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "test-addon",
Namespace: "cluster1",
Annotations: map[string]string{
"addon.open-cluster-management.io/v1alpha1-install-namespace": "test-namespace",
},
},
Spec: addonv1alpha1.ManagedClusterAddOnSpec{
InstallNamespace: "test-namespace",
Configs: []addonv1alpha1.AddOnConfig{
{
ConfigGroupResource: addonv1alpha1.ConfigGroupResource{
Group: "addon.open-cluster-management.io",
Resource: "addondeploymentconfigs",
},
ConfigReferent: addonv1alpha1.ConfigReferent{
Name: "config1",
Namespace: "default",
},
},
},
},
Status: addonv1alpha1.ManagedClusterAddOnStatus{
Namespace: "open-cluster-management-agent-addon",
Registrations: []addonv1alpha1.RegistrationConfig{
{
SignerName: "kubernetes.io/kube-apiserver-client",
Subject: addonv1alpha1.Subject{
User: "system:addon:test",
},
},
},
ConfigReferences: []addonv1alpha1.ConfigReference{
{
ConfigGroupResource: addonv1alpha1.ConfigGroupResource{
Group: "addon.open-cluster-management.io",
Resource: "addondeploymentconfigs",
},
ConfigReferent: addonv1alpha1.ConfigReferent{
Name: "config1",
Namespace: "default",
},
DesiredConfig: &addonv1alpha1.ConfigSpecHash{
ConfigReferent: addonv1alpha1.ConfigReferent{
Name: "config1",
Namespace: "default",
},
SpecHash: "hash123",
},
},
},
SupportedConfigs: []addonv1alpha1.ConfigGroupResource{
{
Group: "addon.open-cluster-management.io",
Resource: "addondeploymentconfigs",
},
},
RelatedObjects: []addonv1alpha1.ObjectReference{
{
Group: "apps",
Resource: "deployments",
Name: "test-deployment",
},
},
AddOnMeta: addonv1alpha1.AddOnMeta{
DisplayName: "Test AddOn",
Description: "Test description",
},
HealthCheck: addonv1alpha1.HealthCheck{
Mode: addonv1alpha1.HealthCheckModeCustomized,
},
},
},
},
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
dst := &internalv1alpha1.ManagedClusterAddOn{}
if err := tc.src.ConvertTo(dst); err != nil {
t.Fatalf("ConvertTo() failed: %v", err)
}
if diff := cmp.Diff(tc.expected, dst); diff != "" {
t.Errorf("ConvertTo() mismatch (-want +got):\n%s", diff)
}
})
}
}
func TestManagedClusterAddOnConvertFrom(t *testing.T) {
cases := []struct {
name string
src *internalv1alpha1.ManagedClusterAddOn
expected *ManagedClusterAddOn
}{
{
name: "complete conversion with all fields",
src: &internalv1alpha1.ManagedClusterAddOn{
ManagedClusterAddOn: addonv1alpha1.ManagedClusterAddOn{
ObjectMeta: metav1.ObjectMeta{
Name: "test-addon",
Namespace: "cluster1",
},
Spec: addonv1alpha1.ManagedClusterAddOnSpec{
InstallNamespace: "test-namespace",
Configs: []addonv1alpha1.AddOnConfig{
{
ConfigGroupResource: addonv1alpha1.ConfigGroupResource{
Group: "addon.open-cluster-management.io",
Resource: "addondeploymentconfigs",
},
ConfigReferent: addonv1alpha1.ConfigReferent{
Name: "config1",
Namespace: "default",
},
},
},
},
Status: addonv1alpha1.ManagedClusterAddOnStatus{
Namespace: "open-cluster-management-agent-addon",
Registrations: []addonv1alpha1.RegistrationConfig{
{
SignerName: "kubernetes.io/kube-apiserver-client",
Subject: addonv1alpha1.Subject{
User: "system:addon:test",
},
},
},
ConfigReferences: []addonv1alpha1.ConfigReference{
{
ConfigGroupResource: addonv1alpha1.ConfigGroupResource{
Group: "addon.open-cluster-management.io",
Resource: "addondeploymentconfigs",
},
ConfigReferent: addonv1alpha1.ConfigReferent{
Name: "config1",
Namespace: "default",
},
DesiredConfig: &addonv1alpha1.ConfigSpecHash{
ConfigReferent: addonv1alpha1.ConfigReferent{
Name: "config1",
Namespace: "default",
},
SpecHash: "hash123",
},
},
},
SupportedConfigs: []addonv1alpha1.ConfigGroupResource{
{
Group: "addon.open-cluster-management.io",
Resource: "addondeploymentconfigs",
},
},
RelatedObjects: []addonv1alpha1.ObjectReference{
{
Group: "apps",
Resource: "deployments",
Name: "test-deployment",
},
},
AddOnMeta: addonv1alpha1.AddOnMeta{
DisplayName: "Test AddOn",
Description: "Test description",
},
HealthCheck: addonv1alpha1.HealthCheck{
Mode: addonv1alpha1.HealthCheckModeCustomized,
},
},
},
},
expected: &ManagedClusterAddOn{
ManagedClusterAddOn: addonv1beta1.ManagedClusterAddOn{
TypeMeta: metav1.TypeMeta{
Kind: "ManagedClusterAddOn",
APIVersion: "addon.open-cluster-management.io/v1beta1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "test-addon",
Namespace: "cluster1",
Annotations: map[string]string{
"addon.open-cluster-management.io/v1alpha1-install-namespace": "test-namespace",
},
},
Spec: addonv1beta1.ManagedClusterAddOnSpec{
Configs: []addonv1beta1.AddOnConfig{
{
ConfigGroupResource: addonv1beta1.ConfigGroupResource{
Group: "addon.open-cluster-management.io",
Resource: "addondeploymentconfigs",
},
ConfigReferent: addonv1beta1.ConfigReferent{
Name: "config1",
Namespace: "default",
},
},
},
},
Status: addonv1beta1.ManagedClusterAddOnStatus{
Namespace: "open-cluster-management-agent-addon",
Registrations: []addonv1beta1.RegistrationConfig{
{
Type: addonv1beta1.KubeClient,
KubeClient: &addonv1beta1.KubeClientConfig{
Subject: addonv1beta1.KubeClientSubject{
BaseSubject: addonv1beta1.BaseSubject{
User: "system:addon:test",
},
},
},
},
},
ConfigReferences: []addonv1beta1.ConfigReference{
{
ConfigGroupResource: addonv1beta1.ConfigGroupResource{
Group: "addon.open-cluster-management.io",
Resource: "addondeploymentconfigs",
},
DesiredConfig: &addonv1beta1.ConfigSpecHash{
ConfigReferent: addonv1beta1.ConfigReferent{
Name: "config1",
Namespace: "default",
},
SpecHash: "hash123",
},
},
},
SupportedConfigs: []addonv1beta1.ConfigGroupResource{
{
Group: "addon.open-cluster-management.io",
Resource: "addondeploymentconfigs",
},
},
RelatedObjects: []addonv1beta1.ObjectReference{
{
Group: "apps",
Resource: "deployments",
Name: "test-deployment",
},
},
AddOnMeta: addonv1beta1.AddOnMeta{
DisplayName: "Test AddOn",
Description: "Test description",
},
HealthCheck: addonv1beta1.HealthCheck{
Mode: addonv1beta1.HealthCheckModeCustomized,
},
},
},
},
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
dst := &ManagedClusterAddOn{}
if err := dst.ConvertFrom(tc.src); err != nil {
t.Fatalf("ConvertFrom() failed: %v", err)
}
if diff := cmp.Diff(tc.expected, dst); diff != "" {
t.Errorf("ConvertFrom() mismatch (-want +got):\n%s", diff)
}
})
}
}