mirror of
https://github.com/open-cluster-management-io/ocm.git
synced 2026-02-14 10:00:11 +00:00
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 🤖 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>
188 lines
6.8 KiB
Go
188 lines
6.8 KiB
Go
package helpers
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"k8s.io/apimachinery/pkg/api/meta"
|
|
"k8s.io/apimachinery/pkg/labels"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
|
|
operatorlister "open-cluster-management.io/api/client/operator/listers/operator/v1"
|
|
operatorapiv1 "open-cluster-management.io/api/operator/v1"
|
|
"open-cluster-management.io/sdk-go/pkg/basecontroller/factory"
|
|
)
|
|
|
|
const (
|
|
// ClusterManagerDefaultNamespace is the default namespace of clustermanager
|
|
ClusterManagerDefaultNamespace = "open-cluster-management-hub"
|
|
// KlusterletDefaultNamespace is the default namespace of klusterlet
|
|
KlusterletDefaultNamespace = "open-cluster-management-agent"
|
|
// BootstrapHubKubeConfig is the secret name of bootstrap kubeconfig secret to connect to hub
|
|
BootstrapHubKubeConfig = "bootstrap-hub-kubeconfig" // #nosec G101
|
|
// HubKubeConfig is the secret name of kubeconfig secret to connect to hub with mtls
|
|
HubKubeConfig = "hub-kubeconfig-secret"
|
|
// ExternalHubKubeConfig is the secret name of kubeconfig secret to connecting to the hub cluster.
|
|
ExternalHubKubeConfig = "external-hub-kubeconfig"
|
|
// ExternalManagedKubeConfig is the secret name of kubeconfig secret to connecting to the managed cluster
|
|
// Only applicable to Hosted mode, klusterlet-operator uses it to install resources on the managed cluster.
|
|
ExternalManagedKubeConfig = "external-managed-kubeconfig"
|
|
// ExternalManagedKubeConfigRegistration is the secret name of kubeconfig secret to connecting to the managed cluster
|
|
// Only applicable to Hosted mode, registration-agent uses it to connect to the managed cluster.
|
|
ExternalManagedKubeConfigRegistration = "external-managed-kubeconfig-registration"
|
|
// ExternalManagedKubeConfigWork is the secret name of kubeconfig secret to connecting to the managed cluster
|
|
// Only applicable to Hosted mode, work-agent uses it to connect to the managed cluster.
|
|
ExternalManagedKubeConfigWork = "external-managed-kubeconfig-work"
|
|
// ExternalManagedKubeConfigAgent is the secret name of kubeconfig secret to connecting to the managed cluster
|
|
// Only applicable to SingletonHosted mode, agent uses it to connect to the managed cluster.
|
|
ExternalManagedKubeConfigAgent = "external-managed-kubeconfig-agent"
|
|
|
|
RegistrationWebhookSecret = "registration-webhook-serving-cert"
|
|
RegistrationWebhookService = "cluster-manager-registration-webhook"
|
|
WorkWebhookSecret = "work-webhook-serving-cert" // #nosec G101
|
|
WorkWebhookService = "cluster-manager-work-webhook"
|
|
AddonWebhookSecret = "addon-webhook-serving-cert" // #nosec G101
|
|
AddonWebhookService = "cluster-manager-addon-webhook"
|
|
|
|
SignerSecret = "signer-secret"
|
|
CaBundleConfigmap = "ca-bundle-configmap"
|
|
|
|
GRPCServerSecret = "grpc-server-serving-cert" //#nosec G101
|
|
)
|
|
|
|
func ClusterManagerNamespace(clustermanagername string, mode operatorapiv1.InstallMode) string {
|
|
if IsHosted(mode) {
|
|
return clustermanagername
|
|
}
|
|
return ClusterManagerDefaultNamespace
|
|
}
|
|
|
|
func KlusterletSecretQueueKeyFunc(klusterletLister operatorlister.KlusterletLister) factory.ObjectQueueKeysFunc {
|
|
return func(obj runtime.Object) []string {
|
|
accessor, _ := meta.Accessor(obj)
|
|
namespace := accessor.GetNamespace()
|
|
name := accessor.GetName()
|
|
interestedObjectFound := false
|
|
if name == HubKubeConfig || name == BootstrapHubKubeConfig || name == ExternalManagedKubeConfig {
|
|
interestedObjectFound = true
|
|
}
|
|
if !interestedObjectFound {
|
|
return []string{}
|
|
}
|
|
|
|
klusterlets, err := klusterletLister.List(labels.Everything())
|
|
if err != nil {
|
|
return []string{}
|
|
}
|
|
|
|
if klusterlet := FindKlusterletByNamespace(klusterlets, namespace); klusterlet != nil {
|
|
return []string{klusterlet.Name}
|
|
}
|
|
|
|
return []string{}
|
|
}
|
|
}
|
|
|
|
func KlusterletDeploymentQueueKeyFunc(klusterletLister operatorlister.KlusterletLister) factory.ObjectQueueKeysFunc {
|
|
return func(obj runtime.Object) []string {
|
|
accessor, _ := meta.Accessor(obj)
|
|
namespace := accessor.GetNamespace()
|
|
name := accessor.GetName()
|
|
interestedObjectFound := false
|
|
if strings.HasSuffix(name, "-agent") {
|
|
interestedObjectFound = true
|
|
}
|
|
if !interestedObjectFound {
|
|
return []string{}
|
|
}
|
|
|
|
klusterlets, err := klusterletLister.List(labels.Everything())
|
|
if err != nil {
|
|
return []string{}
|
|
}
|
|
|
|
if klusterlet := FindKlusterletByNamespace(klusterlets, namespace); klusterlet != nil {
|
|
return []string{klusterlet.Name}
|
|
}
|
|
|
|
return []string{}
|
|
}
|
|
}
|
|
|
|
func ClusterManagerDeploymentQueueKeyFunc(clusterManagerLister operatorlister.ClusterManagerLister) factory.ObjectQueueKeysFunc {
|
|
return func(obj runtime.Object) []string {
|
|
accessor, _ := meta.Accessor(obj)
|
|
name := accessor.GetName()
|
|
namespace := accessor.GetNamespace()
|
|
interestedObjectFound := false
|
|
|
|
if strings.HasSuffix(name, "registration-controller") ||
|
|
strings.HasSuffix(name, "registration-webhook") ||
|
|
strings.HasSuffix(name, "work-webhook") ||
|
|
strings.HasSuffix(name, "addon-manager-controller") ||
|
|
strings.HasSuffix(name, "addon-webhook") ||
|
|
strings.HasSuffix(name, "work-controller") ||
|
|
strings.HasSuffix(name, "placement-controller") {
|
|
interestedObjectFound = true
|
|
}
|
|
if !interestedObjectFound {
|
|
return []string{}
|
|
}
|
|
|
|
clustermanagers, err := clusterManagerLister.List(labels.Everything())
|
|
if err != nil {
|
|
return []string{}
|
|
}
|
|
|
|
clustermanager, err := FindClusterManagerByNamespace(namespace, clustermanagers)
|
|
if err != nil {
|
|
return []string{}
|
|
}
|
|
|
|
return []string{clustermanager.Name}
|
|
}
|
|
}
|
|
|
|
func ClusterManagerQueueKeyFunc(clusterManagerLister operatorlister.ClusterManagerLister) factory.ObjectQueueKeysFunc {
|
|
return clusterManagerByNamespaceQueueKeyFunc(clusterManagerLister)
|
|
}
|
|
|
|
func clusterManagerByNamespaceQueueKeyFunc(clusterManagerLister operatorlister.ClusterManagerLister) factory.ObjectQueueKeysFunc {
|
|
return func(obj runtime.Object) []string {
|
|
accessor, _ := meta.Accessor(obj)
|
|
namespace := accessor.GetNamespace()
|
|
|
|
clustermanagers, err := clusterManagerLister.List(labels.Everything())
|
|
if err != nil {
|
|
return []string{}
|
|
}
|
|
|
|
clustermanager, err := FindClusterManagerByNamespace(namespace, clustermanagers)
|
|
if err != nil {
|
|
return []string{}
|
|
}
|
|
|
|
return []string{clustermanager.Name}
|
|
}
|
|
}
|
|
|
|
func FindKlusterletByNamespace(klusterlets []*operatorapiv1.Klusterlet, namespace string) *operatorapiv1.Klusterlet {
|
|
for _, klusterlet := range klusterlets {
|
|
agentNamespace := AgentNamespace(klusterlet)
|
|
if namespace == agentNamespace {
|
|
return klusterlet
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func FindClusterManagerByNamespace(namespace string, clusterManagers []*operatorapiv1.ClusterManager) (*operatorapiv1.ClusterManager, error) {
|
|
for i := range clusterManagers {
|
|
if clusterManagers[i].Name == namespace ||
|
|
(clusterManagers[i].Spec.DeployOption.Mode == operatorapiv1.InstallModeDefault && namespace == ClusterManagerDefaultNamespace) {
|
|
return clusterManagers[i], nil
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("no match for namespace %s", namespace)
|
|
}
|